在C++中可能会有点长!这是一个完整的工作示例,请注意,如果您更改查询,则需要相应地更改“query”字符串。
SELECT ProcessorId FROM Win32_Processor
to
SELECT * FROM Win32_Processor
然后您可以使用
QueryValue
函数查询任何属性值。
HRESULT GetCpuId(char* cpuId, int bufferLength)
memset(cpuId, 0, bufferLength);
result = QueryValue(pService,
L"SELECT ProcessorId FROM Win32_Processor", L"ProcessorId",
cpuId, bufferLength);
if (FAILED(result))
pService->Release();
pLocator->Release();
CoUninitialize();
return NOERROR;
}
首先,您需要完成所有初始化工作,它们被封装在这两个函数中:
HRESULT InitializeCom()
return NOERROR;
}
HRESULT GetWbemService(IWbemLocator** pLocator, IWbemServices** pService)
result =
完成这个步骤后,你可以运行WQL查询,然后枚举返回的属性以找到你需要的那个属性(尽管可能有更简单的方法,但通过这种方式可以查询多个值)。请注意,如果你从Win32_Processor查询所有值,则会得到大量数据。在某些系统上,我曾经看到它需要2秒钟才能完成查询和枚举属性(因此请过滤查询,仅包括你需要的数据)。
HRESULT QueryValue(IWbemServices* pService, const wchar_t* query, const wchar_t* propertyName, char* propertyValue, int maximumPropertyValueLength)
{
USES_CONVERSION;
IEnumWbemClassObject* pEnumerator = NULL;
HRESULT result = pService->ExecQuery(
bstr_t(L"WQL"),
bstr_t(query),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator
);
if (FAILED(result))
return result;
IWbemClassObject *pQueryObject = NULL;
while (pEnumerator)
{
try
{
ULONG returnedObjectCount = 0;
result = pEnumerator->Next(WBEM_INFINITE, 1, &pQueryObject, &returnedObjectCount);
if (returnedObjectCount == 0)
break;
VARIANT objectProperty;
result = pQueryObject->Get(propertyName, 0, &objectProperty, 0, 0);
if (FAILED(result))
{
if (pEnumerator != NULL)
pEnumerator->Release();
if (pQueryObject != NULL)
pQueryObject->Release();
return result;
}
if ((objectProperty.vt & VT_BSTR) == VT_BSTR)
{
strcpy_s(propertyValue, maximumPropertyValueLength, OLE2A(objectProperty.bstrVal));
break;
}
VariantClear(&objectProperty);
}
catch (...)
{
if (pEnumerator != NULL)
pEnumerator->Release();
if (pQueryObject != NULL)
pQueryObject->Release();
return NOERROR;
}
}
if (pEnumerator != NULL)
pEnumerator->Release();
if (pQueryObject != NULL)
pQueryObject->Release();
return NOERROR;
}
注意: 如果您需要收集比CPU的简单ID更多的信息,则此代码很有用。这是一个通用示例,可从WQL查询(与C#中所做的一样)获取一个(或多个)属性。如果您不需要获取任何其他信息(并且您不打算在C++程序中使用WMI),则可以使用如评论中发布的__cpuid()
内置函数。
__cpuid()
来自WMI的ProcessorId
属性具有以下描述:
描述处理器功能的处理器信息。对于x86类CPU,字段格式取决于CPUID指令的处理器支持情况。如果支持该指令,则属性包含两个DWORD格式的值。第一个是08h-0Bh的偏移量,它是在将输入EAX设置为1时CPUID指令返回的EAX值。第二个是0Ch-0Fh的偏移量,它是指令返回的EDX值。属性的前两个字节是显著的,并包含CPU重置时DX寄存器的内容-所有其他字节都设置为0(零),并且内容以DWORD格式表示。
一个良好的实现应该检查更多关于奇怪的情况,但是一个天真的实现可能是:
std::string GetProcessorId()
{
int info[4] = { -1 };
__cpuid(info, 0);
if (info[0] < 1)
return "";
__cpuid(info, 1);
int family = info[0];
int features = info[3];
std::stringstream id;
id << std::hex << std::setw(4) << std::setfill('0') << family << features;
return id.str();
}
此外,这篇帖子提供了一种更好的C++实现方法。