How to get data from WMI using app C?

I have a pure C application that calls IOCTL calls for my adapter driver and displays information, however this is compiled using Visual Developer Studio 5 (unmanaged code) ... I need to get some information, however, from my adapter using WMI .... My Google search efforts show that I will need to write a C ++ application using COM to achieve any form of communication with wMI or C # with a .NET application a) Is this really so? NO working for my C application? b) If the above is true, what are the minimum level changes that I will need to perform with the project settings / wp / workspace?

Thanks Som

+6
c wmi
source share
2 answers

You can call COM from C. The syntax is somewhat less friendly than C ++, but it works. COM was originally designed to work with C or C ++, and native C language support is included in the COM and WMI header files. It will be a long time, but ... your program will be responsible for allocating all the necessary objects, checking the error conditions from each COM call and releasing the objects created by it.

When using documentation written with C ++ in mind, convert the form COM calls:

pSomething->Method(arg1, ...); // C++ 

in

 pSomething->lpVtbl->Method(pSomething, arg1, ...); // C 

Below is the shortest C code snippet I could get in order to actually pull some information from WMI. If successful, he should list the processors on your computer, as well as their clock frequency in MHz. The program takes care of utilizing the resources that it allocates, but it does not check for errors at all (you must look at these hr values ​​before continuing with each step).

This is the visual studio 2008 "Win32 Console Application" with the main file renamed to the .c extension and the additional stdafx files removed. To link the program, be sure to include wbemuuid.lib in the project properties in the "Configuration Properties" / "Linker / Input / Additional Dependencies" section. It worked successfully in my Vista folder.

 #define _WIN32_WINNT 0x0400 #define _WIN32_DCOM #include <stdio.h> #include <tchar.h> #include <windows.h> #include <wbemidl.h> void _tmain(int argc, _TCHAR* argv[]) { // result code from COM calls HRESULT hr = 0; // COM interface pointers IWbemLocator *locator = NULL; IWbemServices *services = NULL; IEnumWbemClassObject *results = NULL; // BSTR strings we'll use (http://msdn.microsoft.com/en-us/library/ms221069.aspx) BSTR resource = SysAllocString(L"ROOT\\CIMV2"); BSTR language = SysAllocString(L"WQL"); BSTR query = SysAllocString(L"SELECT * FROM Win32_Processor"); // initialize COM hr = CoInitializeEx(0, COINIT_MULTITHREADED); hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); // connect to WMI hr = CoCreateInstance(&CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, &IID_IWbemLocator, (LPVOID *) &locator); hr = locator->lpVtbl->ConnectServer(locator, resource, NULL, NULL, NULL, 0, NULL, NULL, &services); // issue a WMI query hr = services->lpVtbl->ExecQuery(services, language, query, WBEM_FLAG_BIDIRECTIONAL, NULL, &results); // list the query results if (results != NULL) { IWbemClassObject *result = NULL; ULONG returnedCount = 0; // enumerate the retrieved objects while((hr = results->lpVtbl->Next(results, WBEM_INFINITE, 1, &result, &returnedCount)) == S_OK) { VARIANT name; VARIANT speed; // obtain the desired properties of the next result and print them out hr = result->lpVtbl->Get(result, L"Name", 0, &name, 0, 0); hr = result->lpVtbl->Get(result, L"MaxClockSpeed", 0, &speed, 0, 0); wprintf(L"%s, %dMHz\r\n", name.bstrVal, speed.intVal); // release the current result object result->lpVtbl->Release(result); } } // release WMI COM interfaces results->lpVtbl->Release(results); services->lpVtbl->Release(services); locator->lpVtbl->Release(locator); // unwind everything else we've allocated CoUninitialize(); SysFreeString(query); SysFreeString(language); SysFreeString(resource); } 
+13
source share

Another option, if you want to preserve the impact on an existing existing C application, is to write a DLL that internally can use the C ++ and COM shell classes to request WMI information.

This DLL can provide a simple C interface to adapt to your application. The way I will go.

+2
source share

All Articles