|
|
Victor Chen, (C++ 爱好者)5 A4 d- ~& J+ I9 X$ v
T& f) ^0 f5 ]% K
2 @* y6 o' V% {4 [5 @--------------------------------------------------------------------------------) t% u' `% m$ h! }
WMI: Windows Management Instrumentation (Windows 管理工具)
. D1 l! z5 V4 O0 r* F' w5 A 通过 WMI 可以获取主板、BIOS、磁盘、显卡、网络等几乎所有的系统信息。 ; n: r4 g5 ]- s8 y5 y
利用这个工具可以管理本地或客户端系统中几乎所有的信息。& X) X0 I* i9 P8 d, U
很多网络管理工具都是基于WMI开发的。在 Windows NT/2000/XP/2003 都有这个工具, 在 Windows 98 里面可以选择安装这个工具。 7 ?0 z) b% |( N; K
4 f( G4 G. i0 j! d+ F b--------------------------------------------------------------------------------1 n% f, X% @1 Q9 G4 H
BCB 的 WMI 库文件 wbemuuid.lib 由本站提供, 包含在本页下面的程序源码下载里面
6 r! i$ M: B) W0 d( a5 K5 [% Y, J2 e+ |5 N
--------------------------------------------------------------------------------, _' n, ]' ` q" F; |- x0 T$ G
① 初始化 COM 接口:
+ k. q4 _: j q# ?# Y0 b 访问 WMI, 必须先初始化 COM 接口, 在程序的一开始调用 CoInitialize(NULL); 初始化, 在结束时调用 CoUninitialize(); 释放资源。% c/ u3 J; Z7 q2 w+ ^9 i+ d. P4 H
这两个函数在 #include <comdef.h> 里面定义。) V( M, M# Y2 u4 j; t, }, `1 o
4 ]& s/ y0 ^7 N5 `
② 获取访问 WMI 权限:$ x" y+ B" z- t1 p
CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0); M" U2 s- r8 l- Q
如果这个函数返回 S_OK 获取权限成功, 否则为失败。- C5 a4 }& @: k3 l4 X
9 H! p {% J2 Z③ 通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息:- C% F+ v( k4 J' V
这个函数的参数: lpList 返回信息, wsClass 为要查找的系统信息类, 这些 COM 接口在 #include <wbemidl.h> 里定义。2 w8 K9 N& r+ s( y6 [) M
& Q4 `1 a" f+ m7 w, }" {void GetWmiInfo(TStrings *lpList, WideString wsClass)3 d; r5 |9 `9 B/ u. c8 C
{' w+ P' z x3 W" {4 N3 y, Q
IWbemLocator *pWbemLocator = NULL;
1 E2 v$ J: d P3 L5 | if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)
" Z! f# ]9 y4 d {
5 X8 F$ _0 a- X. c* | IWbemServices *pWbemServices = NULL;
: M, c N9 S, E. M X' m$ R WideString wsNamespace = (L"root\\cimv2");
* U2 M, o* z V' F if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)
0 e( ^: S5 [3 Z' j7 q' _1 ~ {( x6 Q' c1 r) ^8 q( }: T
IEnumWbemClassObject *pEnumClassObject = NULL;( }, q9 j5 x G3 J2 |, ]8 \, o
WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;
: R! |( |3 i2 v3 |3 K if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)2 u' |) O& y4 @. Z1 T
{3 i8 f0 h E( k
IWbemClassObject *pClassObject = NULL;' ~0 q8 e' y7 Y# ^+ Z$ q
ULONG uCount = 1, uReturned;8 U7 @; i l( t4 @
if(pEnumClassObject->Reset() == S_OK)) A$ k3 a/ o5 _* o. [9 _
{
; G) C% s% y* j) y int iEnumIdx = 0;( I' k- n+ t8 U" z5 i
while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
+ r. ^8 r" R0 B {, L3 q( Z4 q+ R2 D2 F2 h ?5 T: c
lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");; l5 Q( a( W' o- p. _+ D! Q" K) R
4 q! f. ~+ \! s, J& w, U SAFEARRAY *pvNames = NULL;
0 a3 w' G" b" o, ? if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)
( ]- T6 I( S0 C6 j {
5 o" |. L$ V U5 A; i long vbl, vbu;0 y: H$ [# d: _0 R1 N, j
SafeArrayGetLBound(pvNames, 1, &vbl);3 ], g2 y, h; p8 \+ z) c4 m
SafeArrayGetUBound(pvNames, 1, &vbu);+ _! X9 |( u9 w( k* k
for(long idx=vbl; idx<=vbu; idx++)
0 ?/ E; E. t9 N/ O6 G {9 j! h9 y- k/ J, I
long aidx = idx;; w9 U8 S' @4 R8 d7 I
wchar_t *wsName = 0;; s" ~+ C5 ~* w( j& ^
VARIANT vValue;3 \. G8 Y7 A5 S; [5 `- z- Y
VariantInit(&vValue);
/ T. x. m; ?% b _9 S) l SafeArrayGetElement(pvNames, &aidx, &wsName);
+ Q: O5 R+ |' w( P& A3 t6 o, O; q
BSTR bs = SysAllocString(wsName);
- u, \! ]6 @/ h) a! h! K/ O HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);
6 o5 r+ Q! D1 y- A' N SysFreeString(bs);
6 e* N' k6 b5 S1 ^2 k
0 J/ \; ]5 ?/ q: c' u4 s5 | if(hRes == S_OK)% ]+ }/ o6 p! e4 S
{
% X8 w+ z2 P; ? Y; F, C AnsiString s;3 s$ S- I- s( s0 ~
Variant v = *(Variant*)&vValue;
5 W* N# f1 q6 p3 T1 t- C if(v.IsArray())- {8 ?* W( p6 H5 _2 ?6 N; A+ K- a
{
, N5 O: D1 r* j for(int i=v.ArrayLowBound(); i<=v.ArrayHighBound(); i++)
/ c8 r' b3 v9 H) A {4 a$ ?# X/ u3 ?! n* z" c' F
Variant a = v.GetElement(i);
7 }! K! t( e3 |# \2 l6 X$ w8 T if(!s.IsEmpty())
) k1 f3 N; t* D3 L, \1 N s+=", ";
3 k+ G1 l3 A. ]& o% K! H s+=VarToStr(a);
% ]# p$ M9 t$ G% d6 U, @0 d }
2 i9 \4 a P" W; T }
8 r* s( J( N' k/ y( I& _ else+ T% R2 c8 `( t7 r, X" t4 T
{
# u9 d1 i6 R) Z% Z! l s = VarToStr(v);2 j5 Y) ]5 s9 a# h5 m
}
$ _8 h3 \# V7 p- d% }' X1 \8 ^2 e lpList->Add(AnsiString(wsName)+"="+s);% N4 y9 W4 W# z3 T8 h
} O7 U: C" d3 C( Q* k- K
/ B9 t6 v$ b$ @, Z- e7 Q VariantClear(&vValue);
; K' e" ~" \& N/ k# Z" N SysFreeString(wsName);
" B8 G, J# n4 R* g. p0 [9 e4 [ }
) W# a+ z4 F& i" Y+ J/ P- I+ s }
$ X0 o7 F; u" F( o( q4 _& ?: F' h if(pvNames)SafeArrayDestroy(pvNames);* ]9 e* T. I& R% [3 {
iEnumIdx++;; Q, f1 e% Q* Y
}! W2 I4 j5 B% k& u8 v# X0 X
}
9 f* C- i5 b9 c6 h2 N0 X5 S if(pClassObject)pClassObject->Release();& S" F X3 n9 t+ |7 ]% }) M
}7 Z9 X' J# u6 T
if(pEnumClassObject)pEnumClassObject->Release();
0 |' e6 L5 ^3 h* ~& j) ` }
# K0 ^& J% e0 t5 o if(pWbemServices)pWbemServices->Release();/ n# K* v9 G; K' r+ ^: j
}
. a7 A- b) i3 \' s4 F" f if(pWbemLocator)pWbemLocator->Release();
2 k# Z+ \- l, e, b) K) j C9 |) n}( ]( B4 N+ ^& v) r! A) ?
//---------------------------------------------------------------------------
8 }! I) t& _! u0 S$ p+ q: z/ X& z
// 通过 WIN32_bios 获取 BIOS 信息:% w; f: X2 l7 R; R7 Y- }" _" V
void __fastcall TForm1::Button1Click(TObject *Sender)
9 }+ w2 B6 a2 g5 d{
( B% A/ y4 k% Q" X Memo1->Lines->Add("================== [WIN32_bios] =================");
/ U- N! _! u$ { GetWmiInfo(Memo1->Lines, "WIN32_bios");/ n& f4 L8 i& G. }% s, n# q; ^& E
Memo1->Lines->Add("");* q8 H$ u' K! m* O! k( @# @+ c
}* l8 N _" e; K. w* {. O
% G& D b4 h8 m
--------------------------------------------------------------------------------4 H9 x( R5 H2 o: f
3 e. n) O* b% ^& ?5 k( B$ \/ [
WMI 可以访问的信息类型有:
( g- R: p. k& V' Y Y1 A Win32_1394Controller
, s6 |& @- B. t$ n5 R Win32_BaseBoard
6 q9 [% }. r; k' D/ y Win32_Battery' ^( X) a# t/ q6 N( q( ?- S
Win32_BIOS
, g2 T9 ]. |/ t4 ?, l# v Win32_Bus6 @/ P% E, F& A; Z4 ?5 S
Win32_CacheMemory
u% t& r4 I8 v7 d7 W Win32_CDROMDrive
( s* u( Z' H! z# v- _+ g6 W0 ~ Win32_CurrentProbe
Q) d; K, Y/ e% l8 Z) I Win32_DesktopMonitor& J+ [* z0 U# P- q( g! s9 P$ _6 j
Win32_DeviceMemoryAddress
) |' T' F. M# _ r3 O+ X Win32_DiskDrive
$ W# ]. i' ?, q( ?- ~# Y4 E Win32_DisplayConfiguration
5 ~( g) A- D: Y% T' W9 T" A, N. s Win32_DisplayControllerConfiguration
. i4 d5 A( A; e7 a+ R Win32_DMAChannel
' }& d# G5 q$ a3 _ Win32_Fan9 c/ Q; c) K. F/ o
Win32_FloppyController% i6 F1 Y7 q& G Y% i
Win32_FloppyDrive4 m: I! e! J J1 Q% r
Win32_HeatPipe
0 w5 W' W4 Q! B. ^7 L, n, c0 L Win32_IDEController
: `1 Z+ Q2 K/ j7 z. ]$ B Win32_InfraredDevice
% k- j0 Z- n% I1 g Win32_IRQResource" o0 {6 i$ W- w$ g
Win32_Keyboard
6 v4 ~; j1 A T) m5 C Win32_MemoryArray
6 z6 I* g( _8 H' U; c, i Win32_MemoryDevice! C* F# ^" Z+ d" d& U* J
Win32_MotherboardDevice
1 N$ y! q+ C# m+ h8 R Win32_NetworkAdapter+ R" G- y4 Y$ N$ {" t
Win32_NetworkAdapterConfiguration
6 j9 C0 S( R& F/ o/ @* K Win32_OnBoardDevice
* r' N+ K- g: S5 k+ O+ ]7 L- h Win32_ParallelPort* v- d1 j! c0 |, g+ x9 Y
Win32_PCMCIAController0 N/ F' Z. o7 H2 o% V( E$ J
Win32_PhysicalMemory
/ k6 [6 Z" _# b Win32_PhysicalMemoryArray: i- m3 |2 e( W1 `! g
Win32_PnPEntity' F8 D2 j* L$ c: Y N
Win32_PointingDevice
# H3 L) d& P( j, i+ j; f3 d Win32_PortableBattery
1 x, C% | r/ G0 w0 n j Win32_PortConnector
, K0 g, E8 f7 E Win32_PortResource
0 V( Y8 X9 }3 y( p5 F; c Win32_POTSModem2 n% F, `& H5 N9 f; {" J
Win32_PowerManagementEvent/ a8 Z$ X" Q5 J1 E
Win32_Printer. u$ G6 [& }) r
Win32_PrinterConfiguration
' |" a) }$ P& R Win32_PrintJob
" T; a4 Z0 H4 [; N3 L, k+ I c Win32_Processor: Q3 N8 h* x' f. h
Win32_Refrigeration* ?8 e* G5 d; m/ W+ i
Win32_SerialPort% M6 P- L, H, B; D9 S& R! j# o
Win32_SerialPortConfiguration, ?* j, U2 b5 f$ i: V: F& j
Win32_SMBIOSMemory
3 z+ Y) c6 K, n3 l/ P( E/ m Win32_SoundDevice' a$ B( x) i5 ]& L" l
Win32_SystemEnclosure, D, W. u+ l1 k3 g( a4 p5 L; {
Win32_SystemMemoryResource4 H- O* e7 z( q; H% E9 v! D" ?
Win32_SystemSlot
8 w, z$ m) Z+ f1 ] Win32_TapeDrive2 S! M; u1 u+ ^5 {( U3 R, |
Win32_TemperatureProbe
4 H8 O8 F; P: e# M Win32_UninterruptiblePowerSupply
9 \6 h& g* @1 a( r3 d9 Q# [, y Win32_USBController* I& u9 x1 @- b6 N# ^: x; w
Win32_VideoConfiguration
, y: V% I8 ~, R: @ Win32_VideoController
3 ]9 `! T1 v/ ], H, c2 w4 k Win32_VoltageProbe/ ]! o* q* d- i: o, I- C
) \* i2 Z. T( ~) N/ |* [' V
以上类型(字符串值)通过前面写的函数 GetWmiInfo 可以得到相应的信息, 例如 GetWmiInfo(Memo1->Lines, "WIN32_bios"); |
|