A
Alain Dekker
Hi,
I have a working C++ program reading the ProcessorLoad but there are a few
problems which I need some advise on, please. The code I am using is given
at the bottom of this post. Here are my problems:
* The entire process of getting the load (top->bottom) takes about 1000ms.
This is *very* slow. Is this just a limitation of WMI or have I programmed
it inefficiently or is there a better way?
* Much more importantly, the code below is LEAKING MEMORY! If I put "return
byLoad;" right at the top of the function, there is no memory leak. Where is
the leak coming from, I can't work it out!
Here's the code and thanks in advance,
Alain
// Function: ReadProcessorLoad()
BYTE byLoad = 0;
// Frustratingly, every time you need to read from WMI, it appears you must
redo the
// entire WQL (SQL-like) query!
// Initialize the COM library on the current thread
HRESULT hr = S_OK;
if (!m_bComInitialised)
hr = CoInitialize(NULL);
bool bGoodToGo = true;
// Open the overall WMI service provider
if (bGoodToGo && m_pIWbemLocator)
{
BSTR bstrNamespace = SysAllocString(L"root\\cimv2");
hr = m_pIWbemLocator->ConnectServer(bstrNamespace, NULL, NULL, NULL, 0,
NULL, NULL, &m_pWbemServices);
if (hr != S_OK)
bGoodToGo = false;
SysFreeString(bstrNamespace);
}
// Open the WMI class object
if (bGoodToGo && m_pWbemServices)
{
BSTR bstrQuery = SysAllocString(L"Select * from Win32_Processor");
BSTR bstrQL = SysAllocString(L"WQL");
hr = m_pWbemServices->ExecQuery(bstrQL, bstrQuery,
WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &m_pEnumObject);
if (hr != S_OK)
bGoodToGo = false;
SysFreeString(bstrQuery);
SysFreeString(bstrQL);
}
// Reset the object
if (bGoodToGo && m_pEnumObject)
{
hr = m_pEnumObject->Reset();
if (hr != S_OK)
bGoodToGo = false;
}
// Enumerate the object (make sure it has methods and data)
if (bGoodToGo && m_pEnumObject)
{
ULONG uCount = 1, uReturned;
hr = m_pEnumObject->Next(WBEM_INFINITE, uCount, &m_pClassObject,
&uReturned);
if (hr != S_OK)
bGoodToGo = false;
}
// Read the processor load
if (bGoodToGo && m_pClassObject)
{
BSTR bstrClassProp = SysAllocString(L"LoadPercentage");
HRESULT hr = m_pClassObject->Get(bstrClassProp, 0, &m_vData, 0, 0);
if (SUCCEEDED(hr))
{
// Convert BSTR to ANSI
_bstr_t bstrData = &m_vData;
char* strData = (char*)bstrData;
// Get data
byLoad = atoi(strData);
}
SysFreeString(bstrClassProp);
}
return byLoad;
I have a working C++ program reading the ProcessorLoad but there are a few
problems which I need some advise on, please. The code I am using is given
at the bottom of this post. Here are my problems:
* The entire process of getting the load (top->bottom) takes about 1000ms.
This is *very* slow. Is this just a limitation of WMI or have I programmed
it inefficiently or is there a better way?
* Much more importantly, the code below is LEAKING MEMORY! If I put "return
byLoad;" right at the top of the function, there is no memory leak. Where is
the leak coming from, I can't work it out!
Here's the code and thanks in advance,
Alain
// Function: ReadProcessorLoad()
BYTE byLoad = 0;
// Frustratingly, every time you need to read from WMI, it appears you must
redo the
// entire WQL (SQL-like) query!
// Initialize the COM library on the current thread
HRESULT hr = S_OK;
if (!m_bComInitialised)
hr = CoInitialize(NULL);
bool bGoodToGo = true;
// Open the overall WMI service provider
if (bGoodToGo && m_pIWbemLocator)
{
BSTR bstrNamespace = SysAllocString(L"root\\cimv2");
hr = m_pIWbemLocator->ConnectServer(bstrNamespace, NULL, NULL, NULL, 0,
NULL, NULL, &m_pWbemServices);
if (hr != S_OK)
bGoodToGo = false;
SysFreeString(bstrNamespace);
}
// Open the WMI class object
if (bGoodToGo && m_pWbemServices)
{
BSTR bstrQuery = SysAllocString(L"Select * from Win32_Processor");
BSTR bstrQL = SysAllocString(L"WQL");
hr = m_pWbemServices->ExecQuery(bstrQL, bstrQuery,
WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &m_pEnumObject);
if (hr != S_OK)
bGoodToGo = false;
SysFreeString(bstrQuery);
SysFreeString(bstrQL);
}
// Reset the object
if (bGoodToGo && m_pEnumObject)
{
hr = m_pEnumObject->Reset();
if (hr != S_OK)
bGoodToGo = false;
}
// Enumerate the object (make sure it has methods and data)
if (bGoodToGo && m_pEnumObject)
{
ULONG uCount = 1, uReturned;
hr = m_pEnumObject->Next(WBEM_INFINITE, uCount, &m_pClassObject,
&uReturned);
if (hr != S_OK)
bGoodToGo = false;
}
// Read the processor load
if (bGoodToGo && m_pClassObject)
{
BSTR bstrClassProp = SysAllocString(L"LoadPercentage");
HRESULT hr = m_pClassObject->Get(bstrClassProp, 0, &m_vData, 0, 0);
if (SUCCEEDED(hr))
{
// Convert BSTR to ANSI
_bstr_t bstrData = &m_vData;
char* strData = (char*)bstrData;
// Get data
byLoad = atoi(strData);
}
SysFreeString(bstrClassProp);
}
return byLoad;