获取CPU的ID代码从C#是在C ++(Getting CPU ID code from C# to

2019-06-23 19:02发布

我有这样的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);
}

Answer 1:

这是一个长一点的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()张贴在评论内在。

__cpuid()

ProcessorId从WMI财产有如下描述:

描述该处理器的功能的处理器的信息。 对于一个86级CPU,场格式取决于处理器支持CPUID指令的。 如果指令被支撑,所述属性包含2(二)DWORD格式化值。 第一种是08H-值0Bh,这是EAX值,一个CPUID指令与输入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();
}

又见这个帖子美好C ++ -杂交实现。



Answer 2:

  1. 如果将获取string类型的ProcessorID(托管代码)非托管代​​码(C ++)的只是这个问题,那么你可以尝试多种选项像使用COM接口或通过一些中间CLR CLI界面或使用正常的本机DLL写作编组你自己的代码。

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



文章来源: Getting CPU ID code from C# to be in C++
标签: c# c++ wmi wql cpuid