如何使用C ++在WMI中获得CPU使用率?

时间:2015-08-28 13:46:22

标签: c++ wmi cpu-usage

我已经阅读过这样的大多数问题。但是当尝试使用c ++获取WMI中的cpu使用值时仍然存在一些问题。

我尝试了两种方法来解决这个问题:

  1. PercentProcessorTime中查询Win32_PerfFormattedData_PerfOS_Processor的值。但是这个值比我想要的要大得多。它可以达到10802692。我的一些代码:
  2. hres = m_pWbemSvc->ExecQuery(
    bstr_t("WQL"),
    bstr_t("SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor where Name='_Total' "),
    WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
    NULL,
    &m_pEnumClsObj
    );
    
    hres = m_pWbemClsObj->Get(L"PercentProcessorTime", 0, &vtProp, 0, 0);
            wcout << "CPU Usage : " << vtProp.ullVal << endl;
            VariantClear(&vtProp);
    
    1. Win32_PerfRawData_PerfOS_Processor获取一些数据,然后使用formula。但是,当我尝试使用此方法时,我总是得到与PercentProcessorTimeTimeStamp_Sys100NS相同的值。是说N1=N2D1=D2。我认为我的代码中肯定存在一些错误
    2.   

      式 - (1-((N2-N1)/(D2-D1)))×100

      unsigned __int64 N1;
      unsigned __int64 D1;
      unsigned __int64 N2;
      unsigned __int64 D2;
      bool result = false;
      
      
      if (getCPUData(&N1, &D1))
      {
          Sleep(1000);
      
          if (getCPUData(&N2, &D2))
          {
              result = true;
          }
      }
      
      //(1 - ((N2 - N1) / (D2 - D1))) * 100;
      

      bool WMI_Util::getCPUData(unsigned __int64 *N, unsigned __int64 *D)
      {
      HRESULT hres;
      ULONG uReturn = 0;
      VARIANT vtProp;
      m_pEnumClsObj = NULL;
      bool result = false;
      
      
      hres = m_pWbemSvc->ExecQuery(
          bstr_t("WQL"),
          bstr_t("SELECT * FROM Win32_PerfRawData_PerfOS_Processor where Name='_Total' "),
          WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
          NULL,
          &m_pEnumClsObj
          );
      
      if (FAILED(hres))
      {
          wcout << L"Query for operating system name failed."
              << L" Error code = 0x"
              << hex << hres << endl;
          m_pWbemSvc->Release();
          m_pWbemLoc->Release();
          CoUninitialize();
      }
      else{
      
          m_pWbemClsObj = NULL;
      
          while (m_pEnumClsObj)
          {
              hres = m_pEnumClsObj->Next(WBEM_INFINITE, 1, &m_pWbemClsObj, &uReturn);
      
              if (0 == uReturn)
                  break;
      
              hres = m_pWbemClsObj->Get(L"PercentProcessorTime", 0, &vtProp, 0, 0);
              *N = vtProp.ullVal;
              VariantClear(&vtProp);
      
              hres = m_pWbemClsObj->Get(L"TimeStamp_Sys100NS", 0, &vtProp, 0, 0);
              *D = vtProp.ullVal;
              VariantClear(&vtProp);
      
              m_pWbemClsObj->Release();
      
        }
          result = true;
      }
      return result;
      ReleaseWMI();
      }
      

      至于WMI的初始化,我按照MSDN中的步骤1-5进行操作。我是否需要在两个不同的WMI连接中获取它们的值?在目前的情况下,我只是在两个不同的时间查询该类。这就是为什么我总是得到相同的值?

1 个答案:

答案 0 :(得分:0)

我的建议是使用'vtProp.bstrVal'而不是'vtProp.ullVal'。 我实现了非常相似的功能,正如你所说的在数字字段中获得了常量值,但我在字符串字段中得到了正确的值。

这是我的方法(没有调试打印):

HRESULT WMI_sdk_services::GetCpuUsage(int &cpuUsage)
{
  bool shouldUninitializeComAfterWmiRequest; //out parameter

  HRESULT hres = PrepareEnumWbemClassObject(true, shouldUninitializeComAfterWmiRequest, L"SELECT * FROM Win32_PerfFormattedData_PerfOS_Processor where Name='_Total'");

  IWbemClassObject *pclsObj = NULL;
  ULONG uReturn = 0;

  if(SUCCEEDED(hres)){

    while (pEnumerator)
    {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, 
            &pclsObj, &uReturn);

        if(0 == uReturn)
        {
            break;
        }

        VARIANT vtProp;

        // Get the value of the 'PercentProcessorTime' property
        hr = pclsObj->Get(L"PercentProcessorTime", 0, &vtProp, 0, 0);

        if (WBEM_S_NO_ERROR != hr) {

            if(pclsObj){
                VariantClear(&vtProp);
                pclsObj->Release(); pclsObj = NULL;
            }
            break;
        }
        cpuUsage = std::stoi(vtProp.bstrVal);

        VariantClear(&vtProp);

        pclsObj->Release(); pclsObj = NULL;           
    }
  }

  return hres;    
}

另一句话:你得到的总CPU使用率不是你的进程CPU使用率。