|
|
Victor Chen, (C++ 爱好者)( s3 ?& v3 U5 e9 u" Z i: v
6 @& F3 H$ _1 G, k7 f5 R% F _5 ?/ u6 d" O8 s/ m2 W8 J
--------------------------------------------------------------------------------2 f8 {' G: V% `
WMI: Windows Management Instrumentation (Windows 管理工具)' `: \- F/ B$ M( {
通过 WMI 可以获取主板、BIOS、磁盘、显卡、网络等几乎所有的系统信息。 0 b* e G) s$ n+ ]
利用这个工具可以管理本地或客户端系统中几乎所有的信息。8 n+ e! C* I! x5 a7 D
很多网络管理工具都是基于WMI开发的。在 Windows NT/2000/XP/2003 都有这个工具, 在 Windows 98 里面可以选择安装这个工具。
* f) x7 P5 R. U& H5 d* S
1 `0 F- u. V3 q7 F# {$ l( s--------------------------------------------------------------------------------" U$ b' m/ f3 k/ x* H* `
BCB 的 WMI 库文件 wbemuuid.lib 由本站提供, 包含在本页下面的程序源码下载里面
- j! `3 v! H1 n; _ L7 X. Q) ~9 U7 J+ ^5 @+ F6 o- L7 P
--------------------------------------------------------------------------------
7 y: K" U u% v: s① 初始化 COM 接口:( L4 }1 `: X9 M$ S, ?( M8 I
访问 WMI, 必须先初始化 COM 接口, 在程序的一开始调用 CoInitialize(NULL); 初始化, 在结束时调用 CoUninitialize(); 释放资源。5 @3 j1 C6 S! L* K3 ~
这两个函数在 #include <comdef.h> 里面定义。+ t! ~2 U2 t/ M' G! O
6 I( H2 k2 z2 y0 i& f② 获取访问 WMI 权限:2 M- `; o" w/ t6 V$ I [
CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);
3 Y0 T6 p7 G1 _& D 如果这个函数返回 S_OK 获取权限成功, 否则为失败。6 T) }% B) _2 x2 `; ?$ E; a
7 O# t& U- _$ {# C- {5 w. C
③ 通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息:
& A3 o4 C1 U5 R1 U' w& ] 这个函数的参数: lpList 返回信息, wsClass 为要查找的系统信息类, 这些 COM 接口在 #include <wbemidl.h> 里定义。
" x/ D$ ? g3 `( ^& I+ E1 k1 g) _* V+ T; J# N7 K9 p
void GetWmiInfo(TStrings *lpList, WideString wsClass) {' K, s- `0 [% [8 D
{0 C) Y1 m% @6 V; N) r/ V8 j
IWbemLocator *pWbemLocator = NULL;
0 P' f/ ^3 [: ^. j if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)5 i3 O$ _" L0 \0 a
{
4 O' s8 T/ J- Q1 i IWbemServices *pWbemServices = NULL;
; Q. p4 F: T- R4 N% W, O9 n WideString wsNamespace = (L"root\\cimv2");
/ b4 R9 P% R3 k% J B4 @ if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)' B* s2 U3 Z- O$ D8 L( [
{ _$ J2 Q) C: X( n7 _6 f
IEnumWbemClassObject *pEnumClassObject = NULL;) M+ d/ E' o/ N9 e
WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;
! [' F E$ K+ l* ` f6 m# H' ]% n, E7 j if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)( r% t% i3 F9 w
{, ?2 e) d; y9 X/ Z* V
IWbemClassObject *pClassObject = NULL;
/ g% {5 j# A) |$ q' z ULONG uCount = 1, uReturned;
3 n0 J3 L* s) E/ J6 I6 t! h if(pEnumClassObject->Reset() == S_OK)5 W& C2 p0 ~. y4 v0 p. q* W T
{2 o8 L% D4 N- q3 ~! |3 L# Z" o( e
int iEnumIdx = 0;
- n% B$ \4 q! F0 ~3 K/ n! A1 A/ \ while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
9 r! j' e" `. a {
6 }. y+ ^& x1 S$ B' U lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");- U# r( H% x) _
9 P9 z2 E2 w6 P4 S SAFEARRAY *pvNames = NULL;# i9 D9 a" ~: z8 d
if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)& Z- R0 q" b2 m4 o! O. M; K
{
& ~) t- U0 q, h' R! ~( v# \ long vbl, vbu;
! \3 f1 z) Z4 a0 ?- _# C SafeArrayGetLBound(pvNames, 1, &vbl);: A$ n4 _. y" }( B* @ R# f: m+ M
SafeArrayGetUBound(pvNames, 1, &vbu);5 R4 \3 n/ u& G1 Z, x
for(long idx=vbl; idx<=vbu; idx++)- O8 C) S7 E) h- W
{6 H+ W0 X& ?: S; @4 b
long aidx = idx;
& H6 K( `7 z6 P8 u$ K wchar_t *wsName = 0;& u' C& N, \0 q0 |+ K
VARIANT vValue;
" m$ k' v! G9 X: k* }' u e VariantInit(&vValue);/ U, o1 K! p1 U g' R! Q$ T; r
SafeArrayGetElement(pvNames, &aidx, &wsName);
& [ Z0 I1 _2 J# ? D
! q- W( H/ p! _ W7 H BSTR bs = SysAllocString(wsName);
2 @+ }; B! {* [# D HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);
9 A) ^; D2 V! B. V' p SysFreeString(bs);. w* o+ M& j/ e. L) K$ P8 P
+ q" _* \7 ]2 y' R+ X$ ~( i if(hRes == S_OK)
0 @; M' W4 l) }# b {6 E- p8 N6 K* ]7 D
AnsiString s;
+ f' ~! p. }+ N+ V, w' a! w Variant v = *(Variant*)&vValue;. U* W4 b. F7 I
if(v.IsArray())- v& V, z% S& A! c4 S- F1 d
{) ~' J/ X& t( U' ^& |
for(int i=v.ArrayLowBound(); i<=v.ArrayHighBound(); i++)# W: N' T# C8 Q% Y' p
{
E- A0 L4 D' J) E- M Variant a = v.GetElement(i);
6 [# f( I- k9 \% x if(!s.IsEmpty())2 e, k/ W( h) c$ e2 \$ }! y
s+=", ";9 M. F% a, G& ~! b4 V. n% P2 M' C
s+=VarToStr(a);3 w1 v" @! q4 D- d8 z6 _( s" F
}
+ C4 t+ ]/ U( e5 k& K# m7 E. Y }
2 P0 P5 T6 Z( [8 c; K else
' u3 _0 K/ B; B- K {/ t4 p$ p z4 U* J- W
s = VarToStr(v);
1 i, c+ N7 p6 k% e, b; Z }
, x" }$ o1 _9 B" x8 p. W2 P, n lpList->Add(AnsiString(wsName)+"="+s);
+ m% Y2 ]& ?8 q5 m( e }
, |1 u: z) c! {7 Y" l* w2 l( |1 H7 t& q6 J2 H+ w
VariantClear(&vValue);5 o+ h' R, ^, J' z
SysFreeString(wsName);2 E5 r; ]9 T2 M5 }" R; K. U8 e
}$ @ F3 ^# D( X! b1 J
}; m2 ^ `* P. ` R, G& Y
if(pvNames)SafeArrayDestroy(pvNames);
4 G. S3 g x: n q iEnumIdx++;) ~$ y! ` F7 c5 x7 @
}
2 x' Z$ ~1 d7 Q1 r }
. J# @" P1 H: V5 x0 H8 g4 S if(pClassObject)pClassObject->Release();
0 ~: P3 b1 e ^" P }6 V p( w) ?- i# q8 f
if(pEnumClassObject)pEnumClassObject->Release();/ y' }9 v+ Y) N
}
" |( F# w/ P- X) C6 d if(pWbemServices)pWbemServices->Release();
0 W# q7 ^1 r% r- L: g, e* V3 Z }
6 y+ Z7 u/ O9 i if(pWbemLocator)pWbemLocator->Release();
4 c& x) U! O& s}
1 E9 u7 E0 v8 u& k//---------------------------------------------------------------------------
5 Q" t& h% Q+ Y1 \( c: A" D! H2 l& q4 r3 b0 |) x e. s$ O
// 通过 WIN32_bios 获取 BIOS 信息:
* ~! I3 ]8 u9 Nvoid __fastcall TForm1::Button1Click(TObject *Sender)7 k$ S0 w$ F T& G) e. X- s
{
( P# t3 a( m/ Q* f; _9 \ Memo1->Lines->Add("================== [WIN32_bios] =================");
. `: l4 h9 t7 U8 P) Y GetWmiInfo(Memo1->Lines, "WIN32_bios");
5 G6 [- [& q& l, [ I; g3 o2 d Memo1->Lines->Add("");6 i- ^$ }1 p( m7 M' x0 M
}$ [) V, M" }% q+ }$ z
( u* Z; b, q H0 h9 \
--------------------------------------------------------------------------------- M; y3 J! O8 ~6 F: c x/ a
' K% v9 h+ j* v5 t- S5 u) F
WMI 可以访问的信息类型有:
; T2 ]* _$ Y7 Y0 m; Y2 s; n Win32_1394Controller
* _3 W/ B2 h' A6 B- |' o+ P Win32_BaseBoard
8 C7 X m/ J5 i: Y/ d0 H Win32_Battery/ ~' r: R" T( z& z
Win32_BIOS) }6 k* r/ R$ q$ ~
Win32_Bus
! A) h8 d: Y( y5 t' ]( ] Win32_CacheMemory
2 X5 u9 h1 ?9 a/ S; a Win32_CDROMDrive
, A* I w' j( Q7 C Win32_CurrentProbe+ G$ S2 Y9 k: y' ?8 T/ w- L
Win32_DesktopMonitor
6 g5 o8 M" y. J: @, A7 w Win32_DeviceMemoryAddress P& f5 a" c- w9 r( m
Win32_DiskDrive
; F* U! I% J& D Win32_DisplayConfiguration5 U/ g+ M) u4 Z4 \, @& O+ O
Win32_DisplayControllerConfiguration
) N M2 M6 ] F3 O6 o$ N2 ` Win32_DMAChannel: ]5 o) W) }% |- S i: W
Win32_Fan6 n" S8 s7 @/ A- Q6 Z
Win32_FloppyController
6 R6 t2 F* z/ e N7 _ Win32_FloppyDrive% E) L; l; d; @* N' p
Win32_HeatPipe
9 r6 d3 y# O$ {9 P3 ^4 L Win32_IDEController
) d& h& \0 D/ `- e1 R9 @4 t: ] Win32_InfraredDevice- ]0 r" C* W! [: K
Win32_IRQResource
8 W3 g" _% F' w" c. p9 y# q Win32_Keyboard8 H8 Y& L' x) y" B+ X
Win32_MemoryArray: z$ D' x7 n4 m# {! l1 {
Win32_MemoryDevice
. a' V- d8 b7 _% `+ S Win32_MotherboardDevice2 ~6 r$ |3 c! @# u0 H
Win32_NetworkAdapter$ L7 g S( t# U9 ?& u+ J% H* d
Win32_NetworkAdapterConfiguration
2 l# { U& n1 l$ ^6 ?) _& I Win32_OnBoardDevice5 T0 k+ s: j) ?. d
Win32_ParallelPort
( x, u% q; e9 _9 ~- i5 r Win32_PCMCIAController, [0 Y8 E3 L1 ?& b9 P+ X
Win32_PhysicalMemory& b7 a1 O+ a5 b8 {5 d8 |+ l
Win32_PhysicalMemoryArray0 p! e9 M3 H+ @ L7 M. @- h
Win32_PnPEntity8 E/ U* e" G8 ^
Win32_PointingDevice
5 k3 J. t$ L7 Q" g, D" J Win32_PortableBattery; U' z* Q* S ?# L1 ~
Win32_PortConnector
& A7 G9 H* f3 ~ Q* _& Z+ `" ?/ f9 r Win32_PortResource
* M" T) P! \. e4 l7 ~* \" w; v Win32_POTSModem
2 X* @& y# P: ?1 A( W7 K% j Win32_PowerManagementEvent
M% t4 q9 @- b Win32_Printer
6 |. g0 [9 R5 e! l# x Win32_PrinterConfiguration! S) e% l+ a ^1 \% P& o8 r& P
Win32_PrintJob$ A. ~- }1 M& `% ^% z- H4 T2 [3 U
Win32_Processor; O- @3 J' y' c& v$ k+ F
Win32_Refrigeration
4 |) A+ B& _3 [+ w( O) I Win32_SerialPort
6 {8 N* v8 Y5 W Win32_SerialPortConfiguration0 D& S4 {/ O" S$ T) G8 v# Q7 ?
Win32_SMBIOSMemory4 z" ~, o. y; R
Win32_SoundDevice; `" v4 s# j# u! w+ Y: p' e6 m
Win32_SystemEnclosure( @; a2 x6 e- f" S2 ]& W
Win32_SystemMemoryResource4 }! E: p% W! ]6 O. j- b
Win32_SystemSlot
; }$ D$ p7 O& b4 v9 H% {$ | Win32_TapeDrive7 x, b! j' G* g- M
Win32_TemperatureProbe
4 P) m% E! }5 i0 }9 { Win32_UninterruptiblePowerSupply
4 A& A4 f2 D9 A' G3 L2 ^. i5 B1 N Win32_USBController
5 M# v2 U! Y9 w# L- z Win32_VideoConfiguration/ d' N# h. ?# o5 b6 N+ k
Win32_VideoController
7 q3 R2 {3 [& F1 A- Y% ] Win32_VoltageProbe
& J6 p6 @- p9 W/ R. S$ z2 _( z7 z
& `/ p$ r( k! u以上类型(字符串值)通过前面写的函数 GetWmiInfo 可以得到相应的信息, 例如 GetWmiInfo(Memo1->Lines, "WIN32_bios"); |
|