#define FAILED(hr) (((HRESULT)(hr)) < 0)
使用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()發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.