前言:最近一直在做关于显卡数据采集的调研工作,也在github上看到了一些三方库比如Python和golang的psutil, python: gpustart,再或者通过wmi或者windowsApi等底层接口 但是都只能获取到显卡的名称以及厂家信息等 无法真正意义上获取到显卡占用率等数据 在或者只能获取到英伟达的显卡数据 (该数据都是通过英伟达所开放出来的命令工具所获取到的) 后通过阅读C++ 的一个windows插件 发现他在底层使用了一个叫openhardwaremonitor的动态库 后开始尝试
结果:
虽然可以在win系统上获取到amd和英伟达以及英特尔显卡的使用率 但是并不准确
结果虽然差强人意,但是起码指明了一道方向 后来通过github上查看该项目的描述时得知 该动态库是从另外一个库中迁移出来的分支 LibreHardwareMonitor
LibreHardwareMonitor
下载地址:下载LibreHardwareMonitor.dll
一个C#实线的可与底层系统进行交互的动态库
2.7start 被众多插件软件所引用
C#语言的动态库,那么在python中如何使用?
pythonnet (一个用python解析.net的三方库 实现了.dll文件的动态引用功能)
安装: pip install pythonnet
使用:
```python
import clr # pythonnet
clr.AddReference(dll)# 加载dll动态库
# 将需要使用的动态库通过 from import进行导入(因libreHardwareMonitor.lib没有文档 所以按照这种导入即可)
from LibreHardwareMonitor.Hardware import Computer
computer = Computer() # 正常实例化即可
```
我们如何知道LibreHardwareMonitor的参数都有哪些呢? 可以通过github上的描述进行查看 这是一个c#的示例
通过该示例 我们可以看到 关于computer初始化完成后有几个属性 可以控制当前.dll动态库对哪些数据进行获取
本次只对该3个参数进行使用, 感兴趣的可以去尝试一下另外4个参数
1. IsCpuEnabled 布尔值 获取CPU时为true
2. IsGpuEnabled 布尔值 获取GPU时为true
3. IsMemoryEnabled 布尔值 获取内存时为true
使用:
import clr
import os, sys
clr.AddReference(path + './LibreHardwareMonitorLib') # 这里不需要加后缀.dll 内部会自动拼接
from LibreHardwareMonitor.Hardware import Computer
computer_tmp = Computer() # 实例这这个类
# computer_tmp.IsCpuEnabled = True # 获取CPU时用
computer_tmp.IsGpuEnabled = True # 获取GPU时用
# computer_tmp.IsMemoryEnabled = True # 获取内存时用
# self.computer_tmp.IsNetworkEnabled = True # 获取网卡数据时使用
computer_tmp.Open()
print(len(computer_tmp.Hardware))
for computer in computer_tmp.Hardware:
computer.Update()
data_dict = []
for s in computer.Sensors:
print("名称为:", s.Name)
# print("元器件名称:", s.Identifier)
print("类型为:", s.SensorType)
print("值是:", s.Value)
sensor_type = str(s.SensorType)
if sensor_type == "Load":
data_dict.append({
str(s.Name).replace("D3D ", ""): s.Value
})
print(data_dict)
结果:
参数:
Hardware:对应python中的列表 对应的是Computer中为true的属性值
Hardware[index].Sensors : 对应的是获取到的具体数据
属性:
Name: 元器件名称
Identifier:资源标识符
SensorType:硬件类型 想起查看下方描述
Parent: 所属父级元器件
Hardware[index].Sensors.SensorType:当前获取到的数据类型(如果存在则显示)
具体实现:
FastApi: 异步web开发框架,提供api访问
pythonnet: 访问.dll文件获取底层交互能力
psutil: 获取内存的具体使用(LibreHardwareMonitor只提供了负载值 未提供对应的总内存以及使用内存的详细值)
完整代码main.py文章来源:https://www.toymoban.com/news/detail-600584.html
import uvicorn
from fastapi import FastAPI, APIRouter
from fastapi.middleware.cors import CORSMiddleware
import clr
import yaml, os, sys
import psutil
from starlette.responses import JSONResponse
sys.path.append(os.getcwd())
app = FastAPI(title="设备信息获取",
description="用于获取windows下显卡,内存,cpu,网卡等使用情况",
version="v0.1")
class GetDeviceInfo:
def __init__(self, dll: str):
clr.AddReference(dll)
from LibreHardwareMonitor.Hardware import Computer
self.computer_tmp = Computer() # 实例这这个类
self.computer_tmp.IsCpuEnabled = True # 获取CPU温度时用
self.computer_tmp.IsGpuEnabled = True # 获取GPU温度时用
self.computer_tmp.IsMemoryEnabled = True # 获取内存时用
# self.computer_tmp.IsNetworkEnabled = True # 获取网卡时用
self.computer_tmp.Open()
@staticmethod
def memory_info()->tuple:
p = psutil.virtual_memory()
return p.total / 1024 / 1024, p.used / 1024 / 1024
def params_hardware(self, index: int) -> dict:
hard = self.computer_tmp.Hardware[index]
hard.Update()
device_data = {}
for i in hard.Sensors:
sensor_type = str(i.SensorType)
if sensor_type == "Load" and sensor_type not in device_data:
device_data["Name"] = hard.Name
device_data["Load"] = i.Value
if index == 2 and "/temperature" in str(i.Identifier):
device_data["temperature"] = i.Value
if sensor_type == "Load" and index == 2:
device_data[str(i.Name).replace("D3D ", "")] = i.Value
if index == 1:
total, used = self.memory_info()
device_data['total'] = total
device_data['used'] = used
return device_data
def run(self):
data_list = []
type_list = ["CPU", "memory", "GPU"]
com_len = len(self.computer_tmp.Hardware)
if com_len > len(type_list):
number = com_len - len(type_list)
[type_list.append("other" + str(i)) for i in range(number)]
for index in range(com_len):
device_info = self.params_hardware(index)
device_info['type'] = type_list[index]
data_list.append(device_info)
return data_list
class Router:
routerApi = APIRouter()
def __init__(self):
# 如果使用Pyinstaller -F 进行编译时,将这里放开, 解决相对路径下找不到可用的.dll文件问题
# path = os.path.dirname(sys.executable)
# self.device = GetDeviceInfo(path + "/lib/LibreHardwareMonitorLib")
self.device = GetDeviceInfo("./lib/LibreHardwareMonitorLib")
async def get_device_info(self):
return JSONResponse(
status_code=200,
content={
"message": "success!",
"code": 200,
"data": self.device.run()
}
)
def router_list(self):
self.routerApi.add_api_route("/deviceInfo", self.get_device_info, methods=["GET"])
def init_service():
# 处理浏览器请求时会出现跨域情况
app.add_middleware(CORSMiddleware,
allow_origins="*",
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"], )
router = Router()
router.router_list()
app.include_router(router.routerApi, prefix="/device")
init_service()
if __name__ == '__main__':
# 也可通过配置文件配置相关启动的host以及域名
#with open("config/config.yaml", mode='r+', encoding='utf-8') as f:
# data = yaml.load(f.read(), Loader=yaml.Loader)
uvicorn.run("__main__:app", host="0.0.0.0", port=9969)
接口:
GET http://localhost:9969/device/deviceInfo
结果:
该服务可直接运行 也可编译后通过.exe进行运行 当前仅支持windows下 暂未支持linux以及mac
已上传至https://github.com/yuanhuihui1203/GetDeviceInfo 各位大佬可以点击一下start支持!文章来源地址https://www.toymoban.com/news/detail-600584.html
到了这里,关于Python 获取windows下硬件数据信息(CPU,内存,英特尔、英伟达、AMD显卡使用率及详细信息)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!