从Python WMI获取CPU信息

2 投票
1 回答
3401 浏览
提问于 2025-04-18 14:36

我正在尝试通过Python的WMI模块获取一些系统信息,但网上提到的很多方法似乎都不管用。我知道用其他语言做这件事会简单一些,但我想尝试用Python来实现,出于某些原因。

我试过使用Win32_TemperatureProbe()这个方法,但返回值是None。我也试过MSAcpi_ThermalZoneTemperature(),但出现了下面的错误。我一直在研究这个问题,但似乎找不到其他的方法或解决这些错误的办法。虽然有很多相关的讨论,但没有一个能解决问题。

这是我目前的代码:

import wmi, platform

#Initiating WMI
c = wmi.WMI(namespace="root\\wmi")

#Setting variables
drive_letter, free_space = [], []
stats = {}

#Getting basic infromation
print(platform.processor())
print(c.MSAcpi_ThermalZoneTemperature()[0].CurrentTemperature/10.0)-273.15

for disk in c.Win32_LogicalDisk(["Caption","FreeSpace"], DriveType=3):
   free_space_GB = round(int((disk.FreeSpace))/1073741824, 2)
   drive_letter.append(str(disk.Caption))
   free_space.append(str(free_space_GB))

stats = {"Free Space":free_space, "Drive Letter":drive_letter}

print(stats)

这是我运行这段代码时得到的输出:

Intel64 Family 6 Model 60 Stepping 3, GenuineIntel
Traceback (most recent call last):
  File "C:\Python34\lib\site-packages\wmi.py", line 817, in query
    return self._namespace.query (wql, self, fields)
  File "C:\Python34\lib\site-packages\wmi.py", line 1009, in query
    return [ _wmi_object (obj, instance_of, fields) for obj in self._raw_query(wql) ]
  File "C:\Python34\lib\site-packages\wmi.py", line 1009, in <listcomp>
    return [ _wmi_object (obj, instance_of, fields) for obj in self._raw_query(wql) ]
  File "C:\Python34\lib\site-packages\win32com\client\dynamic.py", line 247, in __getitem__
    return self._get_good_object_(self._enum_.__getitem__(index))
  File "C:\Python34\lib\site-packages\win32com\client\util.py", line 37, in __getitem__
    return self.__GetIndex(index)
  File "C:\Python34\lib\site-packages\win32com\client\util.py", line 53, in __GetIndex
    result = self._oleobj_.Next(1)
pywintypes.com_error: (-2147217396, 'OLE error 0x8004100c', None, None)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Brandyn\Desktop\Performance_monitor.py", line 12, in <module>
    print(c.MSAcpi_ThermalZoneTemperature()[0].CurrentTemperature/10.0)-273.15
  File "C:\Python34\lib\site-packages\wmi.py", line 819, in query
    handle_com_error ()
  File "C:\Python34\lib\site-packages\wmi.py", line 241, in handle_com_error
    raise klass (com_error=err)
wmi.x_wmi: <x_wmi: Unexpected COM Error (-2147217396, 'OLE error 0x8004100c', None, None)>

当我把命名空间改为null时,错误变成了这个:

Intel64 Family 6 Model 60 Stepping 3, GenuineIntel
Traceback (most recent call last):
  File "C:\Python34\lib\site-packages\wmi.py", line 1145, in __getattr__
    return self._cached_classes (attribute)
  File "C:\Python34\lib\site-packages\wmi.py", line 1156, in _cached_classes
    self._classes_map[class_name] = _wmi_class (self, self._namespace.Get (class_name))
  File "<COMObject winmgmts:>", line 3, in Get
  File "C:\Python34\lib\site-packages\win32com\client\dynamic.py", line 282, in _ApplyTypes_
    result = self._oleobj_.InvokeTypes(*(dispid, LCID, wFlags, retType, argTypes) + args)
pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, 'SWbemServicesEx', 'Not found ', None, 0, -2147217406), None)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Brandyn\Desktop\Performance_monitor.py", line 12, in <module>
    print(c.MSAcpi_ThermalZoneTemperature()[0].CurrentTemperature/10.0)-273.15
  File "C:\Python34\lib\site-packages\wmi.py", line 1147, in __getattr__
    return getattr (self._namespace, attribute)
  File "C:\Python34\lib\site-packages\win32com\client\dynamic.py", line 522, in __getattr__
    raise AttributeError("%s.%s" % (self._username_, attr))
AttributeError: winmgmts:.MSAcpi_ThermalZoneTemperature

这个方法有没有解决办法,或者有没有其他可行的替代方案?还是我应该干脆放弃,去专注于其他语言呢?

1 个回答

1

我也遇到过同样的问题。

对于 Win32_LogicalDisk,你需要把命名空间 root\\wmi 替换成 root\\cimv2。这样在Win7上就能正常工作了。

至于 MSAcpi_ThermalZoneTemperature,我还没有找到解决办法。这个对象看起来是这样的:

    >>> print c.MSAcpi_ThermalZoneTemperature
[dynamic: ToInstance, provider("WMIProv"), WMI, guid("{A1BC18C0-A7C8-11d1-BF3C-00A0C9062910}")]
class MSAcpi_ThermalZoneTemperature : MSAcpi
{
    [key, read] string InstanceName;
    [read] boolean Active;
    [WmiDataId(1), read] uint32 ThermalStamp;
    [WmiDataId(2), read] uint32 ThermalConstant1;
    [WmiDataId(3), read] uint32 ThermalConstant2;
    [WmiDataId(4), read] uint32 Reserved;
    [WmiDataId(5), read] uint32 SamplingPeriod;
    [WmiDataId(6), read] uint32 CurrentTemperature;
    [WmiDataId(7), read] uint32 PassiveTripPoint;
    [WmiDataId(8), read] uint32 CriticalTripPoint;
    [WmiDataId(9), read] uint32 ActiveTripPointCount;
    [WmiDataId(10), MissingValue(0), read, MAX(10)] uint32 ActiveTripPoint[];
};

但是 c.MSAcpi_ThermalZoneTemperature.CurrentTemperature 返回的是 None

有趣的是,如果我们运行以下代码:

import win32com.client
strComputer = "."
objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator")
objSWbemServices = objWMIService.ConnectServer(strComputer,"root\WMI")
colItems = objSWbemServices.ExecQuery("SELECT * FROM MSAcpi_ThermalZoneTemperature")
print repr(colItems)
print len(colItems)

然后调用 print repr(colItems) 会返回 <COMObject <unknown>>,而调用 print len(colItems) 会产生一个异常:

Traceback (most recent call last):
  File "get_wmi_test1.py", line 45, in <module>
    print len(colItems)
  File "C:\Python27\lib\site-packages\win32com\client\dynamic.py", line 228, in
__len__
    return self._oleobj_.Invoke(dispid, LCID, invkind, 1)
pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, u'SWbemObjectSet'
, u'Not supported ', None, 0, -2147217396), None)

我查了一下,似乎这个问题更复杂。可以看看这里:

撰写回答