Reputation: 561
I have read most questions like this .But there are still some problems when try get the value of cpu usage in WMI using c++.
I have tried two ways to solve this problem:
PercentProcessorTime
in Win32_PerfFormattedData_PerfOS_Processor
.But the value is much bigger than I want . It can reach 10802692
. some pieces of my code: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);
Win32_PerfRawData_PerfOS_Processor
,then using the formula.However,when I try this method , I always get same value about PercentProcessorTime
and TimeStamp_Sys100NS
.That is to say N1=N2
and D1=D2
.I think there must be some wrong in my codeFormula - (1- ((N2 - N1) / (D2 - D1))) x 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();
}
As for initialization of WMI, I followed the step1-5 in MSDN. Do I need to get the value of them in two different WMI connection? In current situation , I just query the class in two different time .Is this reason why I always get the same value?
Upvotes: 0
Views: 2464
Reputation: 46
My advice is to use 'vtProp.bstrVal' instead of 'vtProp.ullVal'. I implemented very similar function and as you said got constant values in numeric fields but I got correct value in string field.
Here is my method (without debug printings):
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;
}
Another remark: You get here total CPU usage not your process CPU usage.
Upvotes: 0