一直以来都没有用过WMI, 都是用的PDH来获取系统信息.感觉两者很些相似,都是类似于性能数据库,基本的一些什么硬件软件信息都可以比较全面的获得.只是用VC来调用相对比较繁杂,用VB和C#就方便多了.这些天到MSDN上找了些资料,总算大致搞清了一些编程思路.对于那些很想知道怎么获取诸如CPUID,硬盘ID,BIOS信息以及主板信息的人来说应该有些帮助吧.试着用MSDN的例子乱写了一通,以下是通过WMI获取BIOS的例子,不对之处还请指正 ^_^:
--------------------------------------------------------------------------------
#define _WIN32_DCOM
#include <iostream
using namespace std ;
#include <windows.h
#include <comdef.h
#include <wbemcli.h
#pragma comment(lib, "Wbemuuid")
int main(int argc,char**argv)
{
HRESULT hres ;
// Initialize COM.
hres=CoInitializeEx(0,COINIT_MULTITHREADED);
if(FAILED(hres))
{
cout<<"Failed to initialize COM library. Error code = 0x"
<<hex<<hres<<endl ;
return 1 ;
// Program has failed.
}
// Initialize
hres=CoInitializeSecurity(
NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE,NULL);
if(FAILED(hres))
{
cout<<"Failed to initialize security. Error code = 0x"
<<hex<<hres<<endl ;
CoUninitialize();
return 1 ;
// Program has failed.
}
// Obtain the initial locator to Windows Management on a particular host computer.
IWbemLocator*pLoc=0 ;
hres=CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER,
IID_IWbemLocator,(LPVOID*)&pLoc);
if(FAILED(hres))
{
cout<<"Failed to create IWbemLocator object. Err code = 0x"
<<hex<<hres<<endl ;
CoUninitialize();
return 1 ;
// Program has failed.
}
IWbemServices*pSvc=0 ;
// Connect to the rootcimv2 namespace with the current user and obtain pointer pSvc
// to make IWbemServices calls.
hres=pLoc-ConnectServer(_bstr_t(L"ROOT\CIMV2"),
NULL,NULL,0,NULL,0,0,&pSvc);
if(FAILED(hres))
{
cout<<"Could not connect. Error code = 0x"
<<hex<<hres<<endl ;
pLoc-Release();
CoUninitialize();
return 1 ;
// Program has failed.
}
cout<<"Connected to WMI"<<endl ;
// Set the IWbemServices proxy so that impersonation of the user (client) occurs.
hres=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(hres))
{
cout<<"Could not set proxy blanket. Error code = 0x"
<<hex<<hres<<endl ;
pSvc-Release();
pLoc-Release();
CoUninitialize();
return 1 ;
// Program has failed.
}
// Use the IWbemServices pointer to make requests of WMI.
// Make requests here:
// For example, query for print queues that have more than 10 jobs
IEnumWbemClassObject*pEnumerator=NULL ;
hres=pSvc-ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT * from Win32_BIOS"),
WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);
if(FAILED(hres))
{
cout<<"Query for print queues failed. Error code = 0x"
<<hex<<hres<<endl ;
pSvc-Release();
pLoc-Release();
CoUninitialize();
return 1 ;
// Program has failed.
}
else
{
IWbemClassObject*pInstance=NULL ;
ULONG dwCount ;
while(pEnumerator-Next(
WBEM_INFINITE,
1,
&pInstance,
&dwCount)==S_OK)
{
SAFEARRAY*pvNames=NULL ;
if(pInstance-GetNames(NULL,WBEM_FLAG_ALWAYS|WBEM_MASK_CONDITION_ORIGIN,NULL,&pvNames)==S_OK)
{
long vbl,vbu ;
SafeArrayGetLBound(pvNames,1,&vbl);
SafeArrayGetUBound(pvNames,1,&vbu);
for(long idx=vbl;idx<=vbu;idx++)
{
long aidx=idx ;
wchar_t *wsName=0 ;
VARIANT vValue ;
VariantInit(&vValue);
SafeArrayGetElement(pvNames,&aidx,&wsName);
BSTR bs=SysAllocString(wsName);
hres=pInstance-Get(bs,0,&vValue,NULL,0);
SysFreeString(bs);
if(SUCCEEDED(hres))
{
char szANSIString[MAX_PATH];
WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,wsName,-1,
szANSIString,sizeof(szANSIString),NULL,NULL);
cout<<szANSIString<<" : " ;
switch(vValue.vt)
{
case VT_BSTR :
wprintf(L"%s",V_BSTR(&vValue));
break ;
case VT_I2 :
wprintf(L"%d",V_I2(&vValue));
break ;
case VT_I4 :
wprintf(L"%d",V_I4(&vValue));
break ;
case VT_BOOL :
wprintf(L"%s",V_BOOL(&vValue)?L"TRUE":L"FALSE");
break ;
default:
/*WCHAR tmp[100];
wcscpy(tmp, V_BSTR(&vValue));
char tmp1[MAX_PATH];
WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,tmp,-1,
tmp1,sizeof(tmp1),NULL,NULL);
cout<<tmp1;*/
break;
}
cout<<endl ;
}
SysFreeString(wsName);
}
}
else
{
cout<<"Query for print queues failed. Error code = 0x"
<<hex<<hres<<endl ;
pSvc-Release();
pLoc-Release();
CoUninitialize();
return 1 ;
// Program has failed.
}
if(pvNames)SafeArrayDestroy(pvNames);
}
if(pInstance)pInstance-Release();
}
// Cleanup
// ========
pEnumerator-Release();
pSvc-Release();
pLoc-Release();
CoUninitialize();
return 0;
// Program successfully completed.
}
//-----------------------------------
对于怎么用BCB编, 感觉还容易一点,因为我在类型转换的时候碰到了一些问题,而在BCB中的Variant类做了比较好的封装, 具体代码可以 http://www.cppfans.com上找到.
void GetWmiInfo(TStrings *lpList, WideString wsClass)
{
IWbemLocator *pWbemLocator = NULL;
if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)
{
IWbemServices *pWbemServices = NULL;
WideString wsNamespace = (L"root\cimv2");
if(pWbemLocator-ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)
{
IEnumWbemClassObject *pEnumClassObject = NULL;
WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;
if(pWbemServices-ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)
{
IWbemClassObject *pClassObject = NULL;
ULONG uCount = 1, uReturned;
if(pEnumClassObject-Reset() == S_OK)
{
int iEnumIdx = 0;
while(pEnumClassObject-Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
{
lpList-Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");
SAFEARRAY *pvNames = NULL;
if(pClassObject-GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)
{
long vbl, vbu;
SafeArrayGetLBound(pvNames, 1, &vbl);
SafeArrayGetUBound(pvNames, 1, &vbu);
for(long idx=vbl; idx<=vbu; idx++)
{