|
|
Victor Chen, (C++ 爱好者)1 Y1 m0 h7 f# e
6 @$ x( c; M. c0 w
/ [3 R" N8 J" b2 H
--------------------------------------------------------------------------------5 t S2 c* R0 r0 E
WMI: Windows Management Instrumentation (Windows 管理工具)4 e' R* K# Y0 m* w* j+ |
通过 WMI 可以获取主板、BIOS、磁盘、显卡、网络等几乎所有的系统信息。
- h+ x& ^/ y. ? 利用这个工具可以管理本地或客户端系统中几乎所有的信息。
9 D% c9 J) H+ N4 O) w/ e# G( w 很多网络管理工具都是基于WMI开发的。在 Windows NT/2000/XP/2003 都有这个工具, 在 Windows 98 里面可以选择安装这个工具。
7 E/ i( j' G; B( T# S5 u( j% C$ f4 f" o7 U G4 m, a
--------------------------------------------------------------------------------
, T; h6 ], B4 T; g' S$ [BCB 的 WMI 库文件 wbemuuid.lib 由本站提供, 包含在本页下面的程序源码下载里面
" ^* B" q+ O q! r. a0 s) p1 B w1 ~9 ]& D$ l K! j* J
--------------------------------------------------------------------------------, V8 @" u! ?3 X; N0 H
① 初始化 COM 接口:
3 |( K/ x% q- ], I4 { 访问 WMI, 必须先初始化 COM 接口, 在程序的一开始调用 CoInitialize(NULL); 初始化, 在结束时调用 CoUninitialize(); 释放资源。
) w( c6 J0 Q7 ? 这两个函数在 #include <comdef.h> 里面定义。+ j9 l( u1 }' @
+ S; N3 P" i, `# s0 _- c
② 获取访问 WMI 权限:0 k- b' ?& L# ]9 Y
CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);& k5 e# M: r# ^! {, A4 Y
如果这个函数返回 S_OK 获取权限成功, 否则为失败。0 X. t/ F; O/ Z% {8 V3 g* d2 s. V: t
$ t7 }5 u* v" H3 ]& R% C③ 通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息:; E2 C8 D: Y# h" S4 p
这个函数的参数: lpList 返回信息, wsClass 为要查找的系统信息类, 这些 COM 接口在 #include <wbemidl.h> 里定义。7 s$ o( T7 B7 x" Q/ u
! C J: R$ t( l" Qvoid GetWmiInfo(TStrings *lpList, WideString wsClass)
6 Z6 @9 i6 a P/ D* d r: S{
+ A+ y* r6 H! h p8 j1 m# d IWbemLocator *pWbemLocator = NULL;
- k7 ?) ^( o6 v" U2 B9 e& _/ y if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)' U% X6 {, M9 c
{
6 D2 W+ Q( G# W% q' a5 Y IWbemServices *pWbemServices = NULL;& ^2 \; Y, ?3 Q8 T8 `& w
WideString wsNamespace = (L"root\\cimv2");
5 ]( N! E7 r+ K8 l* w9 e4 i if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)
' @8 K- q$ F3 _* S% ^! X9 ? {
3 r' l6 z( C% W/ ^0 w& } IEnumWbemClassObject *pEnumClassObject = NULL;8 N9 R, p7 C% j, r
WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;; g8 `3 s: ]2 O( U+ R4 U: T
if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)
4 U# H; V9 E5 J8 f' |; @ {, H3 V! l# S7 j& T7 k4 Z
IWbemClassObject *pClassObject = NULL;" Y/ _1 E( B! ]" _
ULONG uCount = 1, uReturned;
* I5 M* P2 P L if(pEnumClassObject->Reset() == S_OK)
# |% u; T) a* {5 U {1 ^5 ^1 T1 B* o# W
int iEnumIdx = 0;
$ X4 k& q9 V$ s6 H0 y8 i" p while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
7 O/ C) X( ?4 ]# a L1 l* Y2 B {- r, E! N: O1 i
lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");
& R1 p6 ?) Q! g+ y' N% y P j6 k1 D' f, }
SAFEARRAY *pvNames = NULL;( |) @# u# V& x
if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)
3 R. a2 o. X& k& x& s4 M1 m) Q {9 p6 L; l0 o# U' U
long vbl, vbu;
6 e7 k* A$ Q& ?" \* u0 c+ O SafeArrayGetLBound(pvNames, 1, &vbl);$ n$ M4 u% S5 @8 G6 S
SafeArrayGetUBound(pvNames, 1, &vbu);
/ B+ [& H. T* A) B for(long idx=vbl; idx<=vbu; idx++)2 ^& U9 h$ n) x: O
{
2 I5 F0 S% F/ G9 Q& D. |# C' n long aidx = idx;) c- M4 u) D4 `5 J% p
wchar_t *wsName = 0;$ T: ~# Z3 r9 f3 u+ K
VARIANT vValue;
& d1 o" r" P# g. Y7 ~8 L VariantInit(&vValue);
, U1 E& W' x. S; ?. E" h SafeArrayGetElement(pvNames, &aidx, &wsName);9 h- Q' ^; {0 ~1 y8 J# d
L4 V _$ ]" q$ x- t8 A BSTR bs = SysAllocString(wsName);& `4 ^# n- H" h; b: N; v
HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);
* x: I( n7 q5 g& E. Z SysFreeString(bs);: B. f" b: z" F1 u% _) f7 c) ~
2 k2 J8 u9 g4 e/ C. P7 p
if(hRes == S_OK)& [) r. A" T3 ?0 A+ L
{
; B H) ~6 a, z AnsiString s;
, m$ `5 k4 f ^7 |! J Variant v = *(Variant*)&vValue;! z0 C+ Z- ^/ ^9 v1 t- w7 m
if(v.IsArray())
) [. u9 o5 b6 ]+ v. A: S+ F$ } {* Z$ q5 F2 q$ i/ P: M
for(int i=v.ArrayLowBound(); i<=v.ArrayHighBound(); i++)4 v( A+ O% L2 v D) l/ M2 T
{, e" {' g6 l! d
Variant a = v.GetElement(i);
6 p" g7 f' p$ r# _9 A! ]3 E5 { if(!s.IsEmpty())& q5 C: g; ~+ [! W3 ]
s+=", ";
5 H9 b- R+ }( {0 h& } x+ c9 p s+=VarToStr(a);+ P: `5 J2 [6 ~2 e" K* C. b6 D
}: w# W, E Y, [0 Z' M
}- K0 v; m5 G; S% }
else5 ^6 A! a; J' z. g j4 e
{: ?' s) t- N1 g" d7 k P' r5 a+ J. D
s = VarToStr(v);6 _; V/ x% N- a5 p% z9 B
}
" c$ b5 l- {( m7 H! J lpList->Add(AnsiString(wsName)+"="+s);, f! }# Z, h, S
}7 B+ H$ a7 M0 z! Y8 S6 z0 A
4 M9 ^6 C' V' J* p- ^' R4 R VariantClear(&vValue);
7 z5 l* A- h+ g6 y+ C7 b' K SysFreeString(wsName);
- w' q# L; I; T1 ^# A: v# L }: G w1 E4 D, C6 b5 D
}
" w0 P6 ^, f# y j) r/ @4 S if(pvNames)SafeArrayDestroy(pvNames);
7 k, }: Q! K1 ^# p" p iEnumIdx++;4 @$ k P0 L0 A0 w
}2 P% O7 j9 c5 J& r3 _
}: b1 |$ ~4 p4 s I( Y6 k
if(pClassObject)pClassObject->Release();
, a3 q9 U/ p" `' l+ i }+ @9 T" a$ x3 z6 N/ M8 B
if(pEnumClassObject)pEnumClassObject->Release();
3 J, _9 Z" u' M' r" V% \: w& y5 v9 A }& [: ]* O- J) {, y
if(pWbemServices)pWbemServices->Release();" L. ?* M4 K2 y. e/ q
}
2 h, G4 L' \) _+ _ if(pWbemLocator)pWbemLocator->Release();. y2 D; p1 Q6 N8 X4 j
}
4 \6 M3 S$ e% M# H2 ~//---------------------------------------------------------------------------
4 Y( n$ k4 p6 C5 N6 k3 t( X$ M& Z& V V3 x! b- J/ f7 \( Y9 p
// 通过 WIN32_bios 获取 BIOS 信息:
: g5 b. a5 S0 [void __fastcall TForm1::Button1Click(TObject *Sender)
& ^# o- q2 R, ? b7 v b{
1 k Q" c4 i% H& G Memo1->Lines->Add("================== [WIN32_bios] =================");4 B. w; N( o( `/ Y4 p! I3 b
GetWmiInfo(Memo1->Lines, "WIN32_bios");4 R) H2 l2 `. L5 |
Memo1->Lines->Add("");! M8 O+ \& G. L; Y- B
}
7 \7 P* i8 J, S& `) H; K
7 L+ L, o: m8 W f& q--------------------------------------------------------------------------------) v( s/ |. ^$ G j
/ }+ T- [% d2 R% ~
WMI 可以访问的信息类型有:
- A/ d: ?1 J9 U% a- m# }/ f Win32_1394Controller
' P. |: ?) k0 C$ c' T1 N9 m! l Win32_BaseBoard
! Z# \) w5 F, C; ]) g1 c Win32_Battery
- E+ }% i, e' g# a Win32_BIOS
3 i; _+ A# o9 e* c- S1 f% ]& m; N Win32_Bus9 F1 P9 R8 ~# X, ~. B% }
Win32_CacheMemory) [4 c+ C' G) {* V7 V/ o O
Win32_CDROMDrive
8 c" X+ k3 O3 v' `! h4 J Win32_CurrentProbe' Q& Z- x; N y. J) u% Y% O" ?; _
Win32_DesktopMonitor
( I: {; p' o; ^: C! L8 {) {1 ^- X Win32_DeviceMemoryAddress
7 j2 i) ?; R1 F; i8 z; }$ b7 N& c Win32_DiskDrive9 u! ]- u, p0 F, S
Win32_DisplayConfiguration1 {+ b. E. q2 l n ]. B! ]
Win32_DisplayControllerConfiguration6 ^$ J' R0 O( ~0 q' N' A3 f+ N% j
Win32_DMAChannel
! M/ l8 _8 F2 p+ l' x$ m. _2 Z Win32_Fan
: A5 G, n. z- H' Z) w Win32_FloppyController
0 j9 l4 U) i$ k: C) s2 P Win32_FloppyDrive6 [6 j0 O I( n2 R; V
Win32_HeatPipe3 x: S+ M* O6 {, _' g
Win32_IDEController
! r: @+ I! J) ` Win32_InfraredDevice
; H9 G H% [4 w6 u. `. H1 w/ V$ k Win32_IRQResource% W' i( t% J5 P
Win32_Keyboard
' Y' m' V+ K, k& q Win32_MemoryArray# z7 R" W4 ?: U& T# u2 s
Win32_MemoryDevice$ [; |( v) m, @% y; q9 s
Win32_MotherboardDevice
) F4 }, A$ l9 _+ Q9 [ Win32_NetworkAdapter
1 j/ E8 ^: K4 }' | Win32_NetworkAdapterConfiguration4 j" v% S$ d) [: q5 P0 |
Win32_OnBoardDevice
: D6 {+ Z: m9 t6 z5 p' i( _& {% n Win32_ParallelPort. p; A7 p6 `+ ]0 e, g f
Win32_PCMCIAController
/ k: X5 E/ \4 D* o5 [; o Win32_PhysicalMemory0 A4 e! U% N" U4 ^) G) ] b, v8 Z
Win32_PhysicalMemoryArray
* A& a! P* c9 P. m/ k/ o Win32_PnPEntity
3 U' [$ d5 W9 u7 V p. a0 S Win32_PointingDevice* F- z* p8 t8 r( h! N' \
Win32_PortableBattery8 p6 B5 h. D' A6 R
Win32_PortConnector; v/ K. p, T' B; M. W o
Win32_PortResource# v) ^- Z4 E# A, X- C
Win32_POTSModem
* C# F$ ]1 k/ ^4 K! H Win32_PowerManagementEvent
& Q( a. i# y4 [4 _ Win32_Printer
+ `1 E5 k+ Z R9 v. Z6 r Win32_PrinterConfiguration1 P4 ]! Y: |9 `
Win32_PrintJob" W r; a, x% _4 M3 m
Win32_Processor2 u8 R$ z7 q% u. @7 b7 S$ n
Win32_Refrigeration
- r/ O3 n7 Y+ Q5 ^1 h& _+ _" l2 Q7 E Win32_SerialPort& ]7 S$ C- m$ I! V" O; U$ I
Win32_SerialPortConfiguration
+ ^7 b- N0 P# g* d+ m2 c, Y Win32_SMBIOSMemory
6 a+ L! t4 _3 M Win32_SoundDevice
; q! k& m! J: @3 N8 X* p+ ` Win32_SystemEnclosure
/ }4 I+ r- A0 s' \ Win32_SystemMemoryResource
0 k6 a# ^9 E z3 G" W Win32_SystemSlot
o6 e' S7 \( ^9 Q Win32_TapeDrive7 v0 H! \& |4 K. R E. c
Win32_TemperatureProbe
; ~" ^! E& A2 b, E Win32_UninterruptiblePowerSupply
" F- |: L# u% O# }# B! J* U# r Win32_USBController
3 Z h* N+ Y1 {3 s2 o, S! [% H( C Win32_VideoConfiguration
, O9 d& F( T l i; @* h Win32_VideoController v& i! q6 [% E8 l4 W) }9 D7 ^1 t, @
Win32_VoltageProbe; `: `5 H" p6 e3 J. s& f. [
5 C; q" V1 u+ T3 `9 G& u3 m' \$ N
以上类型(字符串值)通过前面写的函数 GetWmiInfo 可以得到相应的信息, 例如 GetWmiInfo(Memo1->Lines, "WIN32_bios"); |
|