基于C++的WMI应用编程初探-读取BIOS信息

虽然VBScript等脚本语言实现WMI编程更加方便,但有些时候我们还是不得不使用C++来编程,比如说要追求更好的性能或者是一个基于C++的项目中需要这样的功能等等。

 

下面是用C++实现WMI编程的基本步骤,在这里,我们通过读取BIOS信息来演示如何实现。可以对照参考:

http://www.qingfengju.com/article.asp?id=60(通过一个具体实例来理解WMI脚本编程-读取BIOS信息)。

 

1.初始化COM

WMI提供的API是基于COM的,所以必须首先执行CoInitializeEx 和 CoInitializeSecurity函数,以便访问WMI。

 

这里需要如下定义和头文件:

#define _WIN32_DCOM

#include <windows.h>

 

#include <comdef.h>

#include <wbemidl.h>

#pragma comment(lib, "wbemuuid.lib")

 

#include <iostream>

using namespace std;

 

·CoInitializeEx函数初始化COM接口:

HRESULT hr= CoInitializeEx(0,COINIT_MULTITHREADED);

if (FAILED(hr))

{

    return FALSE;

}

注意这个FAILED 的定义是:
#define FAILED(hr) (((HRESULT)(hr)) < 0)

 

·CoInitializeSecurity函数注册并设置进程的默认的安全值:

hr= CoInitializeSecurity(

        NULL,                       // Security descriptor   

        -1,                            // COM negotiates authentication service

        NULL,                       // Authentication services

        NULL,                       // Reserved

        RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication level for proxies

        RPC_C_IMP_LEVEL_IMPERSONATE,// Default Impersonation level for proxies

        NULL,                  // Authentication info

        EOAC_NONE,          // Additional capabilities of the client or server

        NULL);              // Reserved

 

if (FAILED(hr))

{

    CoUninitialize();

    return FALSE;                 

}

 

2.创建一个到WMI命名空间的连接

WMI并不是运行在我们自己的进程中,需要在WMI和我们的程序中创建一个连接。

 

·CoCreateInstance函数来初始化IwbemLocator接口

IWbemLocator *pLoc = 0;

hr = CoCreateInstance(

        CLSID_WbemLocator,

        0,

        CLSCTX_INPROC_SERVER,

        IID_IWbemLocator,

        (LPVOID *) &pLoc

        );

 

if (FAILED(hr))

{

    CoUninitialize();

    return FALSE;    

}

 

·IWbemLocator::ConnectServer方法连接到WMI

ConnectServer方法返回一个IWbemServices接口的代理,可以用来访问本地或是远程WMI命名空间。

IWbemServices *pSvc = 0;

hr = pLoc->ConnectServer(

        BSTR(L"root\\CIMV2"),

        NULL,

        NULL,

        0,

        NULL,

        0,

        0,

        &pSvc

        );

 

if (FAILED(hr))

{

    pLoc->Release();

    CoUninitialize();

    return FALSE;     

}

3. 设置WMI连接的安全属性

因为IWbemServices代理允许使用进程外对象,但是在COM中,如果没有设置安全属性,是不允许进程间互相访问的。所以需要用CoSetProxyBlanket函数设置IWbemServices代理的安全值。

hr = CoSetProxyBlanket(

        pSvc,

        RPC_C_AUTHN_WINNT,

        RPC_C_AUTHZ_NONE,

        NULL,

        RPC_C_AUTHN_LEVEL_CALL,

        RPC_C_IMP_LEVEL_IMPERSONATE,

        NULL,

        EOAC_NONE

        );

 

if (FAILED(hr))

{

    pSvc->Release();

    pLoc->Release();    

    CoUninitialize();

    return FALSE; 

}

 

4.执行自己需要的操作

WMI通过COM提供了许多用来访问系统数据的接口,这里我们要读取系统的BIOS信息。

·IWbemServices指针向WMI发送请求,获取Win32_BIOS类的实例集合

IEnumWbemClassObject* pEnumerator = NULL;

hr = pSvc->ExecQuery(

        bstr_t("WQL"),

        bstr_t("Select * FROM Win32_BIOS"),

        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,

        NULL,

        &pEnumerator

        );

 

if (FAILED(hr))

{

    pSvc->Release();

    pLoc->Release();

    CoUninitialize();

    return FALSE;

}

 

·遍历IEnumWbemClassObject,输出信息

IWbemClassObject *pclsObj=NULL;

while (pEnumerator)

{

    ULONG uReturn = 0;

    hr = pEnumerator->Next(

            WBEM_INFINITE,

            1,

            &pclsObj,

            &uReturn

            );

 

    if(0 == uReturn)

            break;

 

    VARIANT vtProp;

    hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);

    wcout << vtProp.bstrVal << endl;

    hr = pclsObj->Get(L"Manufacturer", 0, &vtProp, 0, 0);

    wcout << vtProp.bstrVal << endl;

    hr = pclsObj->Get(L"Version", 0, &vtProp, 0, 0);

    wcout << vtProp.bstrVal << endl;

    hr = pclsObj->Get(L"CurrentLanguage", 0, &vtProp, 0, 0);

    wcout << vtProp.bstrVal << endl;

    VariantClear(&vtProp);

}

 

if (pclsObj!=NULL){

    pclsObj->Release();

}

if (pEnumerator!=NULL){

    pEnumerator->Release();

}

 

5.释放资源

pSvc->Release();

pLoc->Release();

CoUninitialize();

 

在我的系统上的输出:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值