|
|
Victor Chen, (C++ 爱好者)
' n7 A/ a+ y3 E/ |* u
9 w- s" N a% I2 L7 E. @
2 ]/ A& c$ c3 M! }2 K! e t3 K--------------------------------------------------------------------------------+ u, D9 [8 v% G5 F3 y4 s: A9 h
WMI: Windows Management Instrumentation (Windows 管理工具)/ Q7 H: Z3 ^6 B' @3 q
通过 WMI 可以获取主板、BIOS、磁盘、显卡、网络等几乎所有的系统信息。 : [2 W. v; R: N# o6 G1 G% V3 C
利用这个工具可以管理本地或客户端系统中几乎所有的信息。" ~7 u; j! X' ?. v% E. N7 y
很多网络管理工具都是基于WMI开发的。在 Windows NT/2000/XP/2003 都有这个工具, 在 Windows 98 里面可以选择安装这个工具。
) x. b/ t+ t9 t1 t% L2 T: v7 m6 K1 E9 W; t3 ~2 z* }
--------------------------------------------------------------------------------
! X0 T j1 v4 n8 H& u( J, ]BCB 的 WMI 库文件 wbemuuid.lib 由本站提供, 包含在本页下面的程序源码下载里面
$ h5 {. a, ?* W# [. M" F" ^+ A$ i1 q$ a, q( [
--------------------------------------------------------------------------------
9 q8 h( h& g+ s3 g( d7 F① 初始化 COM 接口: T" C c$ o( H9 ]) P* T
访问 WMI, 必须先初始化 COM 接口, 在程序的一开始调用 CoInitialize(NULL); 初始化, 在结束时调用 CoUninitialize(); 释放资源。) X- f; S) Z5 p. j8 F
这两个函数在 #include <comdef.h> 里面定义。
: M# N! ]4 v7 Y& [2 C/ r3 A3 }2 g0 j; j& S5 ^
② 获取访问 WMI 权限:
3 g0 v0 t7 U$ o L, H/ s" s: T CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);* v- v6 V) z% j
如果这个函数返回 S_OK 获取权限成功, 否则为失败。% F' S: H" X' i* T" c+ M' u2 [/ [
9 w3 [0 P; {+ }3 r* E# A
③ 通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息:
6 s" g( Z( W% J# c& ?- I 这个函数的参数: lpList 返回信息, wsClass 为要查找的系统信息类, 这些 COM 接口在 #include <wbemidl.h> 里定义。! w% I, M5 S, K% R
/ v- N: `5 U9 K" K" Q* ]void GetWmiInfo(TStrings *lpList, WideString wsClass). Y; M" A/ Q) r4 ~2 w9 f6 ~
{
0 a- M0 v% |$ r1 j: Y IWbemLocator *pWbemLocator = NULL;) f3 v' o* C$ [; H' x8 x
if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)
# `2 w. w: i0 k {
/ u1 |( G, ~5 M: D0 V; S G7 g IWbemServices *pWbemServices = NULL;, f$ P( Z1 w& i0 }) M+ W9 q. K
WideString wsNamespace = (L"root\\cimv2");/ w# E/ t) h- m, M
if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)/ ]3 g' d" d' i1 m# W
{) V, u& a& |: {$ z" E
IEnumWbemClassObject *pEnumClassObject = NULL;
# ]4 l: ~" P' G2 D" S0 N WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;
- D( k+ E% Q) |' Q" j/ x' [% Y, R if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)) `6 M. \0 a- l/ }7 d6 B# ~
{6 R9 _! S& D4 N' Z& h9 @6 Y
IWbemClassObject *pClassObject = NULL;
" Y. u0 I* {& C ULONG uCount = 1, uReturned;
' J5 {+ N0 N1 Y' R0 l9 S if(pEnumClassObject->Reset() == S_OK)
' e1 S8 J9 p. G6 k8 r7 G {
8 I# [: Y8 R( n int iEnumIdx = 0;
7 Y9 q( |2 S5 C2 o while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
: {: N; i: I: |0 T8 A {6 S. s8 ?6 Q' f6 z! Z
lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");" R+ X S9 y. v4 c2 a. g& T
+ {# G5 c0 u9 q, k/ y# i, u
SAFEARRAY *pvNames = NULL;
( h' k7 g/ R4 S5 ^0 q" B if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)
% u/ n* z! c" L5 ` {# b( i {: P3 x
long vbl, vbu;
" H* J6 i3 w2 |& S+ L SafeArrayGetLBound(pvNames, 1, &vbl);
- A3 w+ Z/ P. x# I" t SafeArrayGetUBound(pvNames, 1, &vbu);
# C. Z+ p& b5 S for(long idx=vbl; idx<=vbu; idx++)
# G* K; _) f& E2 o4 Z9 U2 o- i {
4 I4 e+ N; |) A6 k3 \& e# x% A* P long aidx = idx;
9 R* E& y' ?: j* k- K1 u wchar_t *wsName = 0;2 d* T% J J8 H$ q. j: e9 z. t
VARIANT vValue;* n3 v- D5 `7 ? _
VariantInit(&vValue);$ e) Q/ J. f* K& n2 J. F" Q) B
SafeArrayGetElement(pvNames, &aidx, &wsName);
' X8 K1 O$ _7 q& N
/ a9 g% z7 p; j1 @9 f3 J, O BSTR bs = SysAllocString(wsName);5 c+ G: ~4 s+ V( ?
HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);4 o# W4 i8 S, \1 N+ {! ^. ^
SysFreeString(bs);
. G, b- T; g D2 c1 L5 I0 \: D5 P' l( G
if(hRes == S_OK)
2 {/ z A$ m) h0 s; x) Q$ V1 X- ~ {* N0 u0 [" n6 ]5 q
AnsiString s;
5 d! X, l9 e3 z4 R5 E- S! b! i Variant v = *(Variant*)&vValue;
0 ?3 I. f% `9 z6 w" b c" x" q# { if(v.IsArray())
1 s& N8 i7 v( {% [& G1 x {
( G! |2 [# y8 W: _ for(int i=v.ArrayLowBound(); i<=v.ArrayHighBound(); i++)
) V9 g8 V! I4 k; |' \3 Z {
* x) R- |* _/ g- l$ B4 F Variant a = v.GetElement(i);
5 y, M- X+ ~2 |" p if(!s.IsEmpty())
2 b' l, T* j, u4 O7 c+ O5 [ s+=", ";
+ q# a) n. _7 M7 O s+=VarToStr(a);
9 [+ x$ R. B6 {" |2 v+ A }
% M: W5 g! @1 b5 p& G# ` }
1 G# c& w$ a: o else
' v* \' R9 Q! t& i, d {/ e& A! P: [* c a. M
s = VarToStr(v);, i0 ?# S6 c& l
}
; h' f+ o$ U, v% W: Q6 u lpList->Add(AnsiString(wsName)+"="+s);
7 \, J* P6 d; ]. Z: Z }
6 H1 k+ {. w$ f) g# g
7 R" p( g; L( x. _6 B' F VariantClear(&vValue);
& r$ C" w) Z" d SysFreeString(wsName);8 o5 i4 P) y% l
}) F& U$ d$ @! l7 ~9 m4 m# ~" v5 S- Q
}. B4 {$ _) n4 Y6 i, |& n# {4 R
if(pvNames)SafeArrayDestroy(pvNames);
5 ~6 _& N' U* L6 S" ?! B iEnumIdx++;/ i. U' E9 r* t: i B4 Z) N' ]7 {1 O
}# }0 r: d5 j2 F8 v2 D8 O
}! |! b' Y% _5 b6 H
if(pClassObject)pClassObject->Release();2 q% p0 d C1 _0 X# G( S5 \
}# d) R4 p/ h6 o
if(pEnumClassObject)pEnumClassObject->Release();1 S) F# R7 ?4 V" g
}
5 E, [* u! P2 k/ E: `5 m7 W4 D0 _ if(pWbemServices)pWbemServices->Release();( s) |! l7 R2 b! Z
}8 K; L: e; s5 R# U) K; v
if(pWbemLocator)pWbemLocator->Release();
8 v7 ]$ K/ g8 j' x}
. f2 F. R, K" V, ]$ o4 `//---------------------------------------------------------------------------$ I2 t$ z& u5 w9 c
2 h5 Y; Q0 y6 `# S% [1 T// 通过 WIN32_bios 获取 BIOS 信息:
5 C h1 W: ~9 V2 C$ T' Wvoid __fastcall TForm1::Button1Click(TObject *Sender)
/ C! Z; R' ]* s4 F$ T2 Y{ k* ~8 k1 o' M; ]* {% S. a+ I
Memo1->Lines->Add("================== [WIN32_bios] =================");
5 t4 T0 |: _1 }4 M GetWmiInfo(Memo1->Lines, "WIN32_bios");
/ R" s% J3 ]# [! p Memo1->Lines->Add("");5 k' h T2 h _, ~2 y
}% [) s% S6 x' \. m! \$ C) j
1 q( D4 H' ~0 Q3 y& l+ x4 q6 ]--------------------------------------------------------------------------------
: q2 n8 c* R0 E" `. t! n3 d$ h7 ]& d: v( D: g. J
WMI 可以访问的信息类型有:
2 l8 I6 p! ^( x8 U4 } j3 ] Win32_1394Controller; T; B% g+ a* T1 B0 i
Win32_BaseBoard. G% U& ]0 U, e% s, z
Win32_Battery+ P- o% C- _6 J; R$ G" r) l
Win32_BIOS
% B8 b+ H! S. Z! l. T Win32_Bus
4 L! i9 E% f' _7 i( t6 X" @ H Win32_CacheMemory
5 I; _9 t# H4 C Win32_CDROMDrive* Q" \5 g4 C& H2 y
Win32_CurrentProbe
$ s# l. W7 n- T9 u! \. [ Win32_DesktopMonitor) o! X5 d8 }! T$ [% Q
Win32_DeviceMemoryAddress5 E( Y" A1 P' ]( w
Win32_DiskDrive
# V# m; q) W5 M" i) s Win32_DisplayConfiguration
' a( y" f0 l0 g8 K Win32_DisplayControllerConfiguration1 m3 t# r+ N _* h
Win32_DMAChannel: C+ r; Z2 ?8 t! |( y. | l
Win32_Fan% N% E, C3 |( M( M6 d8 y8 N$ S
Win32_FloppyController
( m3 l0 v3 [+ X9 A: L7 ?3 o( h; ? Win32_FloppyDrive8 d( t H" k6 Z! T# ^5 v
Win32_HeatPipe
0 `; a* \) |4 U0 Q Win32_IDEController
3 u$ R |1 m2 y" a Win32_InfraredDevice
: i! Q* K8 z- I; J e9 H6 @ Win32_IRQResource! P0 ~' I* l0 P. d5 d) ~( U) @
Win32_Keyboard
/ c( a3 a& F3 @. q& m/ f Win32_MemoryArray4 @! L# x# h2 I3 @) }- a0 H6 C8 b
Win32_MemoryDevice
; q1 R; R: E3 \% e9 ]# w Win32_MotherboardDevice4 @3 Y: X" N, q5 X$ I* E0 f' l5 H
Win32_NetworkAdapter E7 |$ r8 N: g! F+ Y
Win32_NetworkAdapterConfiguration
+ ~, u! `. j& A$ ] Win32_OnBoardDevice
; l0 M* \6 B% S$ j. t u8 Z7 o3 h6 K Win32_ParallelPort
& a/ Q9 e' `7 C$ L/ j* ]- S1 x7 t+ F Win32_PCMCIAController. b9 J# W8 p4 m5 ~/ q# }" K
Win32_PhysicalMemory4 Z; R3 @0 J2 B
Win32_PhysicalMemoryArray' g, P# }& ^, e0 S$ ]0 ]
Win32_PnPEntity7 D1 y: Y) c( l; A
Win32_PointingDevice: d3 I' ?' [' B
Win32_PortableBattery
5 x K9 `6 I: G6 n3 K, @ Win32_PortConnector! E' x$ Y* c1 W Z
Win32_PortResource% ~- e4 k: _* h6 F
Win32_POTSModem
, I& U% B' x# [" e2 [9 D4 l Win32_PowerManagementEvent0 Y1 ~, ^" r5 n" r0 T( R$ g
Win32_Printer& M# ]. W: D3 F0 x) t5 ?% o- m
Win32_PrinterConfiguration+ a7 w( t0 s; M8 K
Win32_PrintJob; W$ F5 W- U+ y R0 x A
Win32_Processor
& [6 |" b( `9 F! L0 Q! T Win32_Refrigeration
4 }3 \ \* g1 t0 F1 ^; C4 H Win32_SerialPort
2 D! J$ C" U- Z" ?+ e Win32_SerialPortConfiguration2 ~! \! r) A8 |
Win32_SMBIOSMemory7 }5 M# Z7 x [1 _
Win32_SoundDevice
- ^- r) a0 y/ U+ n( q0 R/ N6 ^ Win32_SystemEnclosure
: B1 y: @+ M7 N4 |0 y5 ^& k9 p Win32_SystemMemoryResource
( L9 v$ E( H7 Y4 |6 P/ }/ g Win32_SystemSlot
) ]9 k9 D, _8 }' D/ X8 [ Win32_TapeDrive
$ o x" Q8 T5 a Win32_TemperatureProbe8 Y7 ?6 e& i1 [9 `; Q. A" j+ M' G
Win32_UninterruptiblePowerSupply
2 m1 I2 w* z& i+ I4 u/ K! G6 O Win32_USBController* S" ~( S! ~$ ^& }' `0 o3 _
Win32_VideoConfiguration
- N2 g. ^- h% J; P% D- N Win32_VideoController: T$ s6 |2 T4 {4 a8 C* r: r) X9 w" e
Win32_VoltageProbe# t* h9 A) I/ B8 c# t8 i
* f' b7 C( i! M2 @, N- V0 c
以上类型(字符串值)通过前面写的函数 GetWmiInfo 可以得到相应的信息, 例如 GetWmiInfo(Memo1->Lines, "WIN32_bios"); |
|