博客日历
2025年06月 | ||||||
一 | 二 | 三 | 四 | 五 | 六 | 七 |
26 | 27 | 28 | 29 | 30 | 31 | 1 |
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
存档
2025年03月 2024年
03月 04月 05月 2021年
01月 02月 11月 12月 2020年
02月 03月 04月 05月 06月 07月
09月 2018年
09月 2017年
01月 02月 07月 2016年
01月 04月 07月 08月 11月 12月
2015年
01月 02月 03月 05月 09月 10月
11月 2014年
01月 02月 03月 04月 05月 06月
07月 08月 09月 10月 11月 12月
2013年
01月 02月 03月 04月 05月 06月
07月 08月 09月 10月 11月 12月
2012年
01月 02月 03月 04月 05月 06月
07月 08月 09月 10月 11月 12月
2011年
01月 02月 03月 04月 05月 06月
07月 08月 09月 10月 11月 12月
2010年
01月 02月 03月 04月 05月 06月
07月 08月 09月 10月 11月 12月
2009年
03月 04月 05月 06月 07月 08月
09月 10月 11月 12月
基于C++的WMI应用编程初探-读取BIOS信息
虽然VBScript等脚本语言实现WMI编程更加方便,但有些时候我们还是不得不使用C++来编程,比如说要追求更好的性能或者是一个基于C++的项目中需要这样的功能等等。
下面是用C++实现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)
#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();
在我的系统上的输出:


上一篇: 通过WMI脚本来操作SteadyState,将磁盘保护功能设置为“永久保留所有更改”
下一篇: 简易的WMI操作工具类CWmiUtilities
分类:Win32/C++ 查看次数:18284 发布时间:2009/6/1 14:52:54