|
|
Victor Chen, (C++ 爱好者)/ K3 E; C5 h; c: H7 a6 S2 u! z
& U) D% U$ m: F3 w4 c6 c4 ?, M3 O
Q7 H$ _# v: |) c4 x" E7 H--------------------------------------------------------------------------------: |/ ^* \3 I( S6 C k
WMI: Windows Management Instrumentation (Windows 管理工具)
6 l7 i9 Z+ W5 p* ? 通过 WMI 可以获取主板、BIOS、磁盘、显卡、网络等几乎所有的系统信息。 ! x5 r* T: y) ?7 u
利用这个工具可以管理本地或客户端系统中几乎所有的信息。5 A6 i; @" n# i: L; P6 k; w0 d
很多网络管理工具都是基于WMI开发的。在 Windows NT/2000/XP/2003 都有这个工具, 在 Windows 98 里面可以选择安装这个工具。 , ?) A8 K- X2 I/ n# {; r- K
% U" G0 l+ J$ {; V- l8 a( M7 T--------------------------------------------------------------------------------- T5 i4 d) P/ L
BCB 的 WMI 库文件 wbemuuid.lib 由本站提供, 包含在本页下面的程序源码下载里面: V. r6 L- j( V3 n" X) b$ g
1 L' A1 Y, |- B% d( k/ v+ @/ \% Q) J
--------------------------------------------------------------------------------$ V& }* p% M- a0 t% |5 {! ~; ]
① 初始化 COM 接口:
: ?# {4 h( N! K% E( g; L, I3 V 访问 WMI, 必须先初始化 COM 接口, 在程序的一开始调用 CoInitialize(NULL); 初始化, 在结束时调用 CoUninitialize(); 释放资源。
; D% t6 ^- {# o# s+ n* \! x 这两个函数在 #include <comdef.h> 里面定义。
: d/ F( D# B; m. f1 Z
: D. D4 [/ n) X/ S9 E D② 获取访问 WMI 权限:
: P* D- ~2 P: s' D. y0 k CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);- A' e- z) \- H7 N0 X$ \
如果这个函数返回 S_OK 获取权限成功, 否则为失败。, s+ y6 j7 T0 O& f! U5 A
2 v1 S4 ?4 `* n; q8 K③ 通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息:
- B/ X) A$ @5 V) X# r 这个函数的参数: lpList 返回信息, wsClass 为要查找的系统信息类, 这些 COM 接口在 #include <wbemidl.h> 里定义。5 j. [5 ?2 ~- S/ G
% { n$ z! l1 A* I9 f$ Y
void GetWmiInfo(TStrings *lpList, WideString wsClass)8 @2 E( W- s0 ^8 @4 ^% G9 x
{ O- D0 i0 H) z \1 n
IWbemLocator *pWbemLocator = NULL; N( i6 \5 L' |% ?8 T( b8 I+ V
if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)+ W1 L& F' W! R6 C5 P" s# d( q
{. m R% B8 a0 U
IWbemServices *pWbemServices = NULL;
9 y1 A! a0 ]. ?6 a WideString wsNamespace = (L"root\\cimv2");- X) B5 `" {( A7 x" f
if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)
# C- h, q. T" J U8 F a: R6 y! ^( J {
$ B3 M% Y- F- R! @5 X IEnumWbemClassObject *pEnumClassObject = NULL;
- @4 t% {$ ]+ P! K# W& ^- n$ K WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;- j% ]# F* R9 d+ Q
if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)3 F P5 g% t# a: B
{
; d# \0 @- N5 N0 ^: A4 u IWbemClassObject *pClassObject = NULL;
7 k% q5 y; y5 [* r- ^; `/ s ULONG uCount = 1, uReturned;" K4 d' s$ Z5 F
if(pEnumClassObject->Reset() == S_OK)
o+ q& x2 e9 \& l, T {; c) T9 @ V$ A4 j. R: W8 [3 u
int iEnumIdx = 0;
+ ]& ^2 d6 F1 q I while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
8 i) {$ o8 k' w5 T i* V6 v0 B# u {5 s+ m9 x9 _6 \. z5 Q3 c
lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");# H' q) d+ v: n6 U
8 k2 H8 w/ Z0 d3 a/ v) `& |# V SAFEARRAY *pvNames = NULL;# ^2 O0 e# |9 A
if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)9 H1 x/ M, }. X8 |
{) K% v9 `& v, h7 _. [+ P0 p
long vbl, vbu;9 N. v# y& s, E( b
SafeArrayGetLBound(pvNames, 1, &vbl);
, N+ b$ F& c& [ r1 @# P2 e SafeArrayGetUBound(pvNames, 1, &vbu);
: W3 B9 ~- Y, y* W for(long idx=vbl; idx<=vbu; idx++)% a* q7 s3 o e0 P* ]
{
1 _/ K- O/ a5 _! q long aidx = idx;
7 d, j. c; m a, t& i5 t' t wchar_t *wsName = 0;" t3 e3 q% ^2 i3 X% Y
VARIANT vValue;
! Q5 a+ ^4 X* j4 o8 ] VariantInit(&vValue);
2 p- _, ~# S6 N9 T$ q4 c SafeArrayGetElement(pvNames, &aidx, &wsName);8 v9 ]5 {$ j) K2 f/ w
; v8 _$ M2 u6 {, Y$ f* | BSTR bs = SysAllocString(wsName);
4 f* D3 a( B8 L' x, i HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);4 z" y) u+ @2 F; P5 [; l9 J
SysFreeString(bs);3 N6 F8 Y7 | m! u: S. C' X
: n: x% @+ g- }! f if(hRes == S_OK)
( G3 }- O+ \, U; n7 V8 E0 O {
4 X/ i. @3 O) O6 c4 z7 } AnsiString s;( d# ^. N2 y s7 v' Z; n; v
Variant v = *(Variant*)&vValue;
, e* Y5 ]+ r* v: M. \' z& y) ?7 O if(v.IsArray())
% x6 J6 C0 @& Q9 R8 u( a {( O7 j( ^/ A0 l" _# \# g' E
for(int i=v.ArrayLowBound(); i<=v.ArrayHighBound(); i++)
, C+ Y! o; \6 L7 \ {9 E+ s! t q% D! ]* \: w( Y* V
Variant a = v.GetElement(i);
2 A- L4 w& f4 E1 L7 C, o if(!s.IsEmpty())+ H6 _0 C2 L" M; u3 {. D/ ]- k
s+=", ";& Q6 p' i# c( j
s+=VarToStr(a);
/ _7 O- A! j8 W3 t) z }/ U# {1 K0 e4 j. P4 M& o- A2 G0 A
}; ?8 z" r. r) W3 d* q6 O& U
else
. J; `2 a4 x1 U1 W* g2 A; J' Y {
& _7 u) T7 @7 X j; d! [4 k s = VarToStr(v);
0 N% X) \) ^" x& R) _5 G6 o }
0 Z* f7 o" v( p' l$ O4 x lpList->Add(AnsiString(wsName)+"="+s);1 p C3 y1 R7 d6 [& _, h& k% P* ~
}0 i: Z% v9 D3 a- T4 |+ E0 I+ L
( b# B( o' j# z1 } VariantClear(&vValue);4 p# |/ k! S5 p# F1 y
SysFreeString(wsName); _5 J2 l- K) j' D! m
} D; h( Z* I+ o7 ^6 \
}2 H$ l6 r0 H) g8 ^3 J
if(pvNames)SafeArrayDestroy(pvNames);
- l5 C. b. a, D: T; Y) b, A iEnumIdx++;8 m+ b" g/ m* r4 G8 k
}) Z* G) G1 w" c0 d
}
! s! j0 ?' ]- L, G( i) @0 G5 r( J if(pClassObject)pClassObject->Release();! {$ o z. v% L
}
9 c* s @$ p8 I; F. x% n3 j if(pEnumClassObject)pEnumClassObject->Release();
3 f, e$ o8 G( _ }
% l, V6 D6 P& _/ L5 H if(pWbemServices)pWbemServices->Release();
5 K0 D1 l/ g' r" B p }
! L; Y9 e: g5 b+ |1 S+ d: `0 x. `4 V if(pWbemLocator)pWbemLocator->Release();
5 w o+ ?/ L. R}3 E4 t: w: p" h1 W% i7 S T
//---------------------------------------------------------------------------
' V- F" f/ w- L) L% |* y! v2 }
, q) x/ w: {2 k; y b// 通过 WIN32_bios 获取 BIOS 信息:
' J% Q0 I1 v! fvoid __fastcall TForm1::Button1Click(TObject *Sender)$ ~. e" z' Y1 q7 u
{
c: n- b* T; I4 u Memo1->Lines->Add("================== [WIN32_bios] =================");2 Y4 h& t" u3 v' X4 g2 M% j
GetWmiInfo(Memo1->Lines, "WIN32_bios");
" f/ u0 Q+ V4 i: F+ u Memo1->Lines->Add("");
. `5 p9 d3 i/ ^( }}
* h& }) g# B$ u7 V; w
# d {+ E' H( {7 {) @) H--------------------------------------------------------------------------------
7 s( w2 G2 m* O. J' M) K* f6 F3 y( t- k. m1 t
WMI 可以访问的信息类型有:
& Z" x5 a6 T& c. T2 U Win32_1394Controller ?3 ?5 C6 l$ B6 I6 R9 h# E9 ^
Win32_BaseBoard
( a: P9 M6 Q, Q$ Y1 T# T Win32_Battery' j$ y7 p# g6 p4 S! E, z0 L- @
Win32_BIOS
- d/ L# D9 @) R3 ?* C; k" X! e Win32_Bus% U- K5 R) [6 s2 }8 }7 U e
Win32_CacheMemory) e, b* F* Y2 U5 s# ?
Win32_CDROMDrive2 w/ a, a' j, W. w
Win32_CurrentProbe
' H9 [4 f; K% ?# W* X% c Win32_DesktopMonitor
8 }% b/ E2 L; b N" z1 ` } Win32_DeviceMemoryAddress5 U) y8 d- ~1 N1 u$ z) t3 F
Win32_DiskDrive
1 T' R; \" F5 O% Q4 v Win32_DisplayConfiguration
1 d9 z2 z- h1 H/ s1 ~) Z1 E Win32_DisplayControllerConfiguration
2 L7 v( O8 D0 ?. X Win32_DMAChannel2 [3 T9 b* m! j' O e$ K
Win32_Fan2 k" i1 F: i9 P- E7 L% ~
Win32_FloppyController
5 _2 A7 {5 U4 G2 g5 y Win32_FloppyDrive
6 e8 m4 I" `1 S5 v9 L4 a Win32_HeatPipe
1 ^3 ^4 m) S+ h! }! P, H1 W: C" W Win32_IDEController
4 [2 u" o& T0 m% x% b$ k! m; ^ Win32_InfraredDevice4 T& E# j3 K# E0 P+ g
Win32_IRQResource! [1 z5 o/ U: @9 a6 C
Win32_Keyboard
! k( w$ Y$ M. W Win32_MemoryArray( {; p! i/ b: U: s& s
Win32_MemoryDevice0 E' r8 X$ l, m& \/ w
Win32_MotherboardDevice0 V4 I: I' `) h' s: ^1 \
Win32_NetworkAdapter
. j0 N4 Y/ A& t W3 b6 v Win32_NetworkAdapterConfiguration6 K4 j2 O0 }& C# s- R
Win32_OnBoardDevice
7 a; @) x2 p' c( P8 B# \0 f1 {( ` Win32_ParallelPort) K" Y' t: W0 [% A1 m
Win32_PCMCIAController
, d: N1 N* Z5 U Win32_PhysicalMemory
; `: W4 T# U" W0 x, S Win32_PhysicalMemoryArray
" Q6 }/ E) m' @/ G Win32_PnPEntity
; P+ S0 V+ }3 N9 g Win32_PointingDevice' {9 f7 w! y/ d
Win32_PortableBattery0 ~" f7 Y6 i3 z# [ }
Win32_PortConnector
/ M2 {; G- h+ e) l) J Win32_PortResource( B! O3 O4 y. h0 T2 o
Win32_POTSModem
' S; |- Z L: ^2 R Win32_PowerManagementEvent3 J7 g1 ~1 y) |0 _
Win32_Printer
$ n4 N5 x8 g8 L, T Win32_PrinterConfiguration
+ j% d U& L$ h h Win32_PrintJob- }5 `" p. c) i$ D ^5 m/ C4 @9 b+ z
Win32_Processor3 z3 n# J! x9 Y: Y
Win32_Refrigeration# _' E# G2 Y) p' s0 s/ U1 [
Win32_SerialPort4 O3 n+ D6 X: B r2 U
Win32_SerialPortConfiguration
3 y% i6 P5 z/ n& S1 d* G Win32_SMBIOSMemory. B0 H$ J3 |3 _
Win32_SoundDevice$ k5 _- m$ f. L, n
Win32_SystemEnclosure/ A$ g B) P2 F' k+ }
Win32_SystemMemoryResource
* K8 m9 g5 A( Y. A( @4 D Win32_SystemSlot
7 A3 A; A+ K" |. Q$ | Win32_TapeDrive
9 i! Q4 T- h6 a9 d8 { Win32_TemperatureProbe2 q3 w" ?7 Z4 N
Win32_UninterruptiblePowerSupply
5 M% {8 H7 T! f: Z Win32_USBController
0 y6 B, s7 C# ~2 V: K( r5 O Win32_VideoConfiguration
# h) t2 O, `% Q$ ^! Z; o$ A; g; f' Q Win32_VideoController
* C1 _% ]& s6 P$ S/ D# n Win32_VoltageProbe6 u2 `, j& ?# o% D$ V& g
9 H5 t3 c- T, z7 P
以上类型(字符串值)通过前面写的函数 GetWmiInfo 可以得到相应的信息, 例如 GetWmiInfo(Memo1->Lines, "WIN32_bios"); |
|