用C语言调用WMI

标签: , ,

这只是一篇翻译

你可以用C语言调用WMI。虽然语法有一些不够C++友好,但是它可以工作。COM在初始设计的时候就能在C或C++中工作,COM和WMI的头文件包含对纯C语言的支持。但是程序会比较长……你的程序必须负责为所有对象分配内存,检测每个COM调用的错误,释放它初始化的对象的内存。

在使用用C++格式写的文档的时候,要在心里记着将COM调用从

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

转换成

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

下面就是我可以从WMI获取一些信息的最短的C代码片段。如果运行成功,将返回你电脑上的CPU列表和它们的时钟频率(以MHz为单位)。程序小心的释放了它分配的所有资源,但是没有做任何的错误处理(你必须在继续下一步之前检测hr的值)。

这是一个visual studio 2008(Demon注:经过我的测试,VC6.0也可以)的Win32控制台程序。为了让程序成功编译,确保在工程属性中包含wbemuuid.lib,在Configuration Properties/Linker/Input/Additional Dependencies下。(Demon注:我在程序中多加了一行#pragma comment(lib,"wbemuuid.lib"),可以不用配置)

#define _WIN32_WINNT 0x0400 
#define _WIN32_DCOM 
 
#include <stdio.h> 
#include <tchar.h> 
#include <windows.h> 
#include <wbemidl.h> 
#pragma comment(lib,"wbemuuid.lib")
 
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); 
} 

原文链接:How to obtain data from WMI using a C Application

赞赏

微信赞赏支付宝赞赏

随机文章:

  1. WinDbg 6.12.2.633下载地址
  2. Chrome新标签页无法打开问题的解决
  3. 使用Windows Script Encoder加密VBS
  4. 我为什么不用JScript?
  5. VBS变量名Wsh等于WScript对象?

2 条评论 发表在“用C语言调用WMI”上

  1. 拜托啦说道:

    怎么确保在工程属性中包含wbemuuid.lib???急用

  2. Mike说道:

    不错,已使用。VS2010编译无错。谢谢

留下回复