您的位置:首页 > 编程语言

编程通过WMI获取系统信息

2008-08-26 16:59 483 查看
要了解WMI,请查阅:
http://www.microsoft.com/china/technet/community/scriptcenter/resources/wmifaq.mspx#EJC
WMI是一组COM对象,其接口比较多,详细请参考:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/com_api_for_wmi.asp
WMI的使用平台包括:NT sp4/2000/XP/2003,98可能需要另外安装。一些软件,如优化大师,就是通过该技术获取到本机所有硬件信息。

MSDN上有使用范例:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wmisdk/wmi/example__getting_wmi_data_from_the_local_computer.asp



要获取硬件信息的步骤:
1、 所需头文件,库
#include <wbemidl.h>
#include <Wbemcli.h>
#pragma comment(lib,"Wbemuuid.lib")

2、初始化 COM 接口:
访问 WMI, 必须先初始化 COM 接口, 在程序的一开始调用 CoInitialize(NULL); 初始化, 在结束时调用 CoUninitialize(); 释放资源。

3、获取访问 WMI 权限:
CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT,
RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);
如果这个函数返回 S_OK 获取权限成功, 否则为失败。

4、通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息:




我整理的完整代码:

LRESULT _getWmiInfo(IWbemClassObject *pClassObject)
{
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 i = vbl ; i<= vbu; i++ )
{
long index = i ;
WCHAR *wsName = NULL ;
CComVariant varValue ;
SafeArrayGetElement( pvNames, &index , &wsName ) ;


CComBSTR bstrName ( wsName ) ;
if( pClassObject->Get( bstrName , 0 , &varValue , NULL , 0 ) == S_OK )
{

CString str ;
if( varValue.vt & VT_BSTR )
{
str = varValue.bstrVal ;
}
else if( varValue.vt & VT_ARRAY )
{

long iLowBound = 0 , iUpBound = 0 ;
SafeArrayGetLBound( varValue.parray , 1 , &iLowBound ) ;
SafeArrayGetUBound( varValue.parray , 1 , &iUpBound ) ;

for( long j = iLowBound ; j <= iUpBound ; j ++ )
{
VARIANT *pvar = NULL ;
long temp = j ;
if( SafeArrayGetElement( varValue.parray , &temp , pvar ) == S_OK &&
pvar )
{
CComVariant varTemp ;
if( varTemp.ChangeType( VT_BSTR , pvar ) == S_OK )
{
if( !str.IsEmpty() )
str += _T(",") ;
str += varTemp.bstrVal ;
}
}

}
}
else
{
if( varValue.ChangeType( VT_BSTR ) == S_OK )
str = varValue.bstrVal ;
}


// 打印出硬件信息
TRACE( "%s=%s/n" , CString(bstrName) , str ) ;
}
}
}


if(pvNames)
{
SafeArrayDestroy(pvNames);
return S_OK ;
}

return E_FAIL ;
}

HRESULT GetWmiInfo( LPCTSTR lpszClass )
{
CoInitialize(NULL);

//
// 获取访问 WMI 权限
//
if( CoInitializeSecurity( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT,
RPC_C_IMP_LEVEL_IMPERSONATE,NULL, EOAC_NONE, 0 )
== S_OK )
{
//
// 通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息
//
CComPtr<IWbemLocator> spWbemLocator ;
if( spWbemLocator.CoCreateInstance( CLSID_WbemAdministrativeLocator , 0 ,
CLSCTX_INPROC_SERVER|
CLSCTX_LOCAL_SERVER ) == S_OK )
{
CComPtr<IWbemServices> spWbemServices ;
if( spWbemLocator->ConnectServer( L"root//cimv2" , NULL, NULL, NULL, 0,
NULL, NULL, &spWbemServices ) == S_OK )
{
//
// 检索指定信息
//
USES_CONVERSION ;
CComPtr<IEnumWbemClassObject> spEnumWbemClassObject ;
CComBSTR bstrQuery ( L"Select * from " ) ;
bstrQuery += T2OLE(lpszClass) ;

if( spWbemServices->ExecQuery( L"WQL" , bstrQuery ,
WBEM_FLAG_RETURN_IMMEDIATELY ,
NULL, &spEnumWbemClassObject ) == S_OK )
{
ULONG uCount = 1, uReturned;
CComPtr<IWbemClassObject> spClassObject ;

if( spEnumWbemClassObject->Reset() == S_OK )
{
int iEnumIdx = 0;
while( spEnumWbemClassObject->Next( WBEM_INFINITE,
uCount, &spClassObject, &uReturned) == S_OK )
{
_getWmiInfo( spClassObject ) ;

spClassObject.Release() ;
}

}


}
}
}
}

CoUninitialize();
}

以上代码参考自http://www.cppfans.com/articles/system/bcb_wmi.asp ,先向此文作者表示感谢。代码中在读取硬件信息并转换成字符串的方式可能有不妥之处(即红色字体的代码),你可以根据需要自行修改,如果有好的写法欢迎向我发邮件。
上面有两个函数: _getWmiInfo 和GetWmiInfo ,前者由后者调用,只是为了缩减后者的代码量。后者的参数是你要获取的硬件信息,有效的值有:

Win32_1394Controller
Win32_BaseBoard
Win32_Battery
Win32_BIOS
Win32_Bus
Win32_CacheMemory
Win32_CDROMDrive
Win32_CurrentProbe
Win32_DesktopMonitor
Win32_DeviceMemoryAddress
Win32_DiskDrive
Win32_DisplayConfiguration
Win32_DisplayControllerConfiguration
Win32_DMAChannel
Win32_Fan
Win32_FloppyController
Win32_FloppyDrive
Win32_HeatPipe
Win32_IDEController
Win32_InfraredDevice
Win32_IRQResource
Win32_Keyboard
Win32_MemoryArray
Win32_MemoryDevice
Win32_MotherboardDevice
Win32_NetworkAdapter
Win32_NetworkAdapterConfiguration
Win32_OnBoardDevice
Win32_ParallelPort
Win32_PCMCIAController
Win32_PhysicalMemory
Win32_PhysicalMemoryArray
Win32_PnPEntity
Win32_PointingDevice
Win32_PortableBattery
Win32_PortConnector
Win32_PortResource
Win32_POTSModem
Win32_PowerManagementEvent
Win32_Printer
Win32_PrinterConfiguration
Win32_PrintJob
Win32_Processor
Win32_Refrigeration
Win32_SerialPort
Win32_SerialPortConfiguration
Win32_SMBIOSMemory
Win32_SoundDevice
Win32_SystemEnclosure
Win32_SystemMemoryResource
Win32_SystemSlot
Win32_TapeDrive
Win32_TemperatureProbe
Win32_UninterruptiblePowerSupply
Win32_USBController
Win32_VideoConfiguration
Win32_VideoController
Win32_VoltageProbe

最后是我写的例子,只打印了CPU、主板和硬盘三种硬件信息。例子下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: