我有这个C#代码来获取处理器ID,但我无法将其传递给C ++,我尝试了很多但我真的不能,我刚开始使用C ++而我希望能够获得使用C ++的CPU ID,就像我以前使用C#
一样这是我在C#中的代码:
public static string GetProcessorID()
{
string sProcessorID = "";
string sQuery = "SELECT ProcessorId FROM Win32_Processor";
ManagementObjectSearcher oManagementObjectSearcher = new ManagementObjectSearcher(sQuery);
ManagementObjectCollection oCollection = oManagementObjectSearcher.Get();
foreach (ManagementObject oManagementObject in oCollection)
{
sProcessorID = (string)oManagementObject["ProcessorId"];
}
return (sProcessorID);
}
答案 0 :(得分:6)
在C ++中有点长一点!这是一个完整的工作示例,请注意,如果您从
更改查询SELECT ProcessorId FROM Win32_Processor
到
SELECT * FROM Win32_Processor
然后,您可以使用QueryValue
函数查询任何属性值。
HRESULT GetCpuId(char* cpuId, int bufferLength)
{
HRESULT result = InitializeCom();
if (FAILED(result))
return result;
IWbemLocator* pLocator = NULL;
IWbemServices* pService = NULL;
result = GetWbemService(&pLocator, &pService);
if (FAILED(result))
{
CoUninitialize();
return result;
}
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 result;
}
pService->Release();
pLocator->Release();
CoUninitialize();
return NOERROR;
}
首先,你必须完成所有的初始化工作,它们被打包到这两个函数中:
HRESULT InitializeCom()
{
HRESULT result = CoInitializeEx(0, COINIT_APARTMENTTHREADED);
if (FAILED(result))
return result;
result = CoInitializeSecurity(
NULL, // pSecDesc
-1, // cAuthSvc (COM authentication)
NULL, // asAuthSvc
NULL, // pReserved1
RPC_C_AUTHN_LEVEL_DEFAULT, // dwAuthnLevel
RPC_C_IMP_LEVEL_IMPERSONATE, // dwImpLevel
NULL, // pAuthList
EOAC_NONE, // dwCapabilities
NULL // Reserved
);
if (FAILED(result) && result != RPC_E_TOO_LATE)
{
CoUninitialize();
return result;
}
return NOERROR;
}
HRESULT GetWbemService(IWbemLocator** pLocator, IWbemServices** pService)
{
HRESULT result = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER,
IID_IWbemLocator, reinterpret_cast<LPVOID*>(pLocator));
if (FAILED(result))
{
return result;
}
result = (*pLocator)->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"), // strNetworkResource
NULL, // strUser
NULL, // strPassword
NULL, // strLocale
0, // lSecurityFlags
NULL, // strAuthority
NULL, // pCtx
pService // ppNamespace
);
if (FAILED(result))
{
(*pLocator)->Release();
return result;
}
result = CoSetProxyBlanket(
*pService, // pProxy
RPC_C_AUTHN_WINNT, // dwAuthnSvc
RPC_C_AUTHZ_NONE, // dwAuthzSvc
NULL, // pServerPrincName
RPC_C_AUTHN_LEVEL_CALL, // dwAuthnLevel
RPC_C_IMP_LEVEL_IMPERSONATE, // dwImpLevel
NULL, // pAuthInfo
EOAC_NONE // dwCapabilities
);
if (FAILED(result))
{
(*pService)->Release();
(*pLocator)->Release();
return result;
}
return NOERROR;
}
这样你就可以运行你的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"), // strQueryLanguage
bstr_t(query), // strQuery
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, // lFlags
NULL, // pCtx
&pEnumerator // ppEnum
);
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()
内在函数。
WMI的ProcessorId
属性有以下描述:
描述处理器功能的处理器信息。为 x86类CPU,字段格式取决于处理器的支持 CPUID指令。如果指令受支持,则属性 包含2(两)个DWORD格式的值。第一个是偏移量 08h-0Bh,这是CPUID指令返回的EAX值 输入EAX设置为1.第二个是0Ch-0Fh的偏移量,即 指令返回的EDX值。只有前两个字节 属性很重要,包含DX的内容 在CPU复位时注册 - 所有其他都设置为0(零)和内容 是DWORD格式。
一个好的实现应该检查更多关于奇怪的案例但是一个天真的实现可能是:
std::string GetProcessorId()
{
int info[4] = { -1 };
__cpuid(info, 0);
if (info[0] < 1)
return ""; // Not supported?!
// Up to you...you do not need to mask results and you may use
// features bits "as is".
__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();
}
另请参阅this post以获得更好的C ++ - ish实现。
答案 1 :(得分:0)
如果只是将获得的类型字符串(托管代码)的ProcessorID发送到非托管代码(c ++)的问题,那么您可以尝试各种选项,例如使用COM接口或通过某些中间CLR CLI界面或者使用普通的原生dll编写自己的编组编码。
另一种方法是创建一个C#COM接口并通过调用函数GetProcessorID()