从C#获取CPU ID代码为C ++

我有这个C#代码来获取处理器ID,但我无法将其传递给C ++,我尝试了很多,但我真的不能,我刚开始使用C ++,我希望能够获得CPU ID C ++就像我以前用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); } 

它在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(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()内在函数。

__cpuid()

WMI的ProcessorId属性具有以下描述:

描述处理器function的处理器信息。 对于x86类CPU,字段格式取决于CPUID指令的处理器支持。 如果支持该指令,则该属性包含2(两)个DWORD格式的值。 第一个是08h-0Bh的偏移量,它是CPUID指令返回的EAX值,输入EAX设置为1.第二个是0Ch-0Fh的偏移量,它是指令返回的EDX值。 只有属性的前两个字节是重要的,并且在CPU复位时包含DX寄存器的内容 – 所有其他字节都设置为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(); } 

另请参阅此文章以获得更好的C ++ - ish实现。

  1. 如果只是将获得的类型字符串(托管代码)的ProcessorID发送到非托管代码(c ++)的问题,那么您可以尝试各种选项,例如使用COM接口或通过某些中间CLR CLI界面或使用普通本机dll写入自己编组代码。

  2. 另一种方法是创建一个C#COM接口并通过调用函数GetProcessorID()从C ++访问它以获取sProcessorID