The Code Project Advertise on the CodeProject
All Topics, MFC / C++ >> System >> General

Getting Information from WMI in Visual C++
By Aamir Butt

This is an Article just to describe how to use WMI with Visual C++ 6. I had to do this for one of my projects and I finally came up with this solution. I hope this will be beneficial to others as well. 
  VC6, W2K, ATL
  Posted 15 Jan 2004
Articles by this author
7,601 views
Search:
FAQ
What's New
Lounge
Contribute
Message Boards
Toolbox
Broken links?
VS.NET 2003 for $899
MSDN Univ. from $1950
Print version
Send to a friend

Sign in / Sign up
 Email
 Password
Remember me
Lost your Password?
 


15 members have rated this article. Result:
Popularity: 3.89. Rating: 3.31 out of 5.

Introduction

We normally find a lot of ways and a number of resources to use WMI or to get information from “Windows Management Instrumentation” while using Visual Basic 6 and C#, but I could not find a single resource describing the same thing in Visual C++. MSDN resources are also very limited in this context.

Code

Following is the code on how to get the current processor load from a WMI class Win32_Processor defined in a .mof file. .mof files are managed object files which have a typical way of defining classes and methods.

WMI provides the COM service which is used to connect to the WMI services. The important parts of the code include:

  • bstrNamespace : The initialization of this variable is very tricky. The first three forward slashes //./ represent the Host Computer name from which you want to get information from. A “.” Indicates that information is to be obtained from the Same Computer on which you are working. You can give any Network name here but getting information from network depends upon your Access Rights etc. cimv2 is the namespace containing the Win32_Processor class.
  • pIWbemLocator is the argument in which we get the Interface pointer.
  • After that, we call the function ConnectServer of the pIWbemLocator to get a pointer to pWbemServices.
  • WMI uses its own Query Language to get information known as WQL (the acronym for WMI Query Language). So, when calling the function ExecQuery, we have to specify the language as its first argument. Second argument is the Query itself. Last argument is important because here we get a pointer to an Enumeration object through which we can enumerate through the objects available. This enumeration is important because consider the case that we want to know the information about running processes and we are using Win32_Process class for this purpose. Then through this enumeration object, we can go through different processes one by one.
  • By calling the Reset and Next methods of pEnumObject, we are moving through the objects. We get the pointer to an object in pClassObject.
  • The last function through which we get the Actual value of a property is Get. We pass a BSTR to this function to get the value in a Variant.
CoInitialize(NULL);
IWbemLocator * pIWbemLocator = NULL;
IWbemServices * pWbemServices = NULL;
IEnumWbemClassObject * pEnumObject = NULL;
BSTR bstrNamespace = (L"//./root\\cimv2");
HRESULT hRes = CoCreateInstance (
  CLSID_WbemAdministrativeLocator,
  NULL ,
  CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER , 
  IID_IUnknown ,
  ( void ** ) & pIWbemLocator
  ) ;
if (SUCCEEDED(hRes))
{
  hRes = pIWbemLocator->ConnectServer(
  bstrNamespace, // Namespace
  NULL, // Userid
  NULL, // PW
  NULL, // Locale
  0, // flags
  NULL, // Authority
  NULL, // Context
  &pWbemServices
  );
}
BSTR strQuery = (L"Select * from win32_Processor");
BSTR strQL = (L"WQL");
hRes = pWbemServices->ExecQuery(strQL, strQuery,
  WBEM_FLAG_RETURN_IMMEDIATELY,NULL,&pEnumObject);

ULONG uCount = 1, uReturned;
IWbemClassObject * pClassObject = NULL;
hRes = pEnumObject->Reset();
hRes = pEnumObject->Next(WBEM_INFINITE,uCount, &pClassObject, &uReturned);
VARIANT v;
BSTR strClassProp = SysAllocString(L"LoadPercentage");
hRes = pClassObject->Get(strClassProp, 0, &v, 0, 0);
SysFreeString(strClassProp);

_bstr_t bstrPath = &v; //Just to convert BSTR to ANSI
char* strPath=(char*)bstrPath;
if (SUCCEEDED(hRes))
MessageBox(strPath);
else
MessageBox(”Error in getting object”);
VariantClear( &v );
pIWbemLocator->Release();
pWbemServices->Release();
pEnumObject->Release();
pClassObject->Release();
CoUninitialize();

Conclusion

This was the shortest method I was able to work out to get information from any WMI class. You can simply change the class name in the Query and Property Name while calling Get method and you will get information from all the classes supported in your OS. I tested this code in Windows 2000 Professional. I hope it will work well for Win XP but probably not in previous versions of windows because they don’t support a lot of WMI classes.

About Aamir Butt


Wanna improve my logic, please help me

Click here to view Aamir Butt's online profile.


Other popular System articles:

[Top] Sign in to vote for this article:     PoorExcellent  

Premium Sponsor

Hint: For a faster board use IE 4+ or Mozilla, choose 'Message View' from the View dropdown and hit 'Set Options'.
FAQ  Noise level    Search comments  
  View    Per page  
New thread Msgs 1 to 25 of 32 (Total: 33) (Refresh) First Prev Next Last
Subject  Author  Date 
  Crash !!   Fundoo7  5:53 29 Apr '04 
  Re: Crash !!   Aamir Butt  14:48 29 Apr '04 
  Re: Crash !!   Fundoo7  1:26 30 Apr '04 
  Error returned for ExecQuery Unconfirmed/Anonymous posting  AnandSharma  13:09 22 Mar '04 
  Re: Error returned for ExecQuery Unconfirmed/Anonymous posting  AnandSharma  3:34 23 Mar '04 
  Re: Error returned for ExecQuery   Carolene  4:15 8 Apr '04 
  Re: Error returned for ExecQuery   chankya  4:34 12 Apr '04 
  wbemidl.h file   aman2006  20:42 18 Mar '04 
  Re: wbemidl.h file   DavidCrow  15:11 22 Mar '04 
  Re: wbemidl.h file   Carolene  4:26 8 Apr '04 
  Can't Create IWbemLocator Unconfirmed/Anonymous posting  Rahul Vij  4:26 3 Mar '04 
  Got Wbemidl.h installed   Carolene  7:50 24 Feb '04 
  Re: Got Wbemidl.h installed   Aamir Butt  13:43 24 Feb '04 
  Linking error   ps124  12:50 4 Feb '04 
  Re: Linking error   Marc-Antoine Ruel  15:03 4 Feb '04 
  Re: Linking error   Aamir Butt  12:34 5 Feb '04 
  Re: Linking error   javierMiranda  16:35 5 May '04 
  Problems   bob16972  21:17 23 Jan '04 
  Re: Problems   Aamir Butt  13:19 28 Jan '04 
  Re: Problems   bob16972  19:45 28 Jan '04 
 
Aamir,
I am getting this return from ConnectServer...

WBEM_E_INITIALIZATION_FAILURE
0x80041014
Component, such as a provider, failed to initialize for internal reasons.

I've tried replacing all the initialization code with code from other samples that are working for me but it still apparently has problems elsewhere. I'll keep looking and let you know if I can track down my issue.

Thanks for your response.
 
[Reply][Email][View Thread][Get Link]
  Re: Problems   bob16972  9:53 29 Jan '04 
  Re: Problems   Aamir Butt  7:10 30 Jan '04 
  Re: Problems   bob16972  14:47 30 Jan '04 
  Re: Problems   Martin Hinchy  23:27 9 Feb '04 
  Re: Problems   Aamir Butt  13:08 10 Feb '04 
Last Visit: 11:36 Thursday 6th May, 2004 First Prev Next Last

All Topics, MFC / C++ >> System >> General
Updated: 15 Jan 2004
Editor: Nishant S
Article content copyright Aamir Butt, 2004
everything else Copyright © CodeProject, 1999-2004.
Advertise on The Code Project | Privacy

MSDN Communities | ASPAllianceDeveloper FusionDevelopersDexDevGuruProgrammers HeavenPlanet Source CodeResource IndexTek-Tips ForumsTopXMLVisualBuilderZVONSearch Us!