|
|
Victor Chen, (C++ 爱好者)
! M! j- |- {3 a& U% K/ u, U6 Y1 a, g/ Q: f; S
* E8 B- ]" k: v--------------------------------------------------------------------------------; J6 u2 Z/ s( `4 V5 p
WMI: Windows Management Instrumentation (Windows 管理工具)
, Z; [9 x1 R4 A& C5 y- r% M 通过 WMI 可以获取主板、BIOS、磁盘、显卡、网络等几乎所有的系统信息。
# M1 x$ T, [6 e6 m4 D# M 利用这个工具可以管理本地或客户端系统中几乎所有的信息。
" g+ s) I, s0 R 很多网络管理工具都是基于WMI开发的。在 Windows NT/2000/XP/2003 都有这个工具, 在 Windows 98 里面可以选择安装这个工具。 # q: c8 g( T7 u% m( m
: T1 s4 |! y. x. e9 z9 M
--------------------------------------------------------------------------------2 i4 H1 I- X- H- {8 L1 P3 e+ {
BCB 的 WMI 库文件 wbemuuid.lib 由本站提供, 包含在本页下面的程序源码下载里面
6 W% X5 f% Z7 d8 u, V
# [$ C+ |5 c! z' w+ h4 ?2 q--------------------------------------------------------------------------------$ L) ^0 v3 x1 W$ t8 f+ R
① 初始化 COM 接口:, W3 ]# l- B! g" B7 X
访问 WMI, 必须先初始化 COM 接口, 在程序的一开始调用 CoInitialize(NULL); 初始化, 在结束时调用 CoUninitialize(); 释放资源。
. y/ T3 n6 n6 k8 J6 @2 X 这两个函数在 #include <comdef.h> 里面定义。; Y) v% L. s! l4 Z
8 g! P4 ? U7 \5 K② 获取访问 WMI 权限:' `& N* B: u1 Y" L+ ?% b# r
CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);
0 L9 M; E2 K, }9 m- F6 M 如果这个函数返回 S_OK 获取权限成功, 否则为失败。
+ m* s& n' x o2 r
5 ^% _6 f4 o& I③ 通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息:* }2 q* f& }' C+ H& w
这个函数的参数: lpList 返回信息, wsClass 为要查找的系统信息类, 这些 COM 接口在 #include <wbemidl.h> 里定义。
5 @; G7 U& }! o2 d3 e6 P5 }& h$ @* P
void GetWmiInfo(TStrings *lpList, WideString wsClass)2 ?+ O% \% W8 n$ q4 Q3 ~
{
' ^% O1 t" y% }" H7 G. Q IWbemLocator *pWbemLocator = NULL;
2 M$ `* ` L9 _7 H/ H: ? if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK), J0 Q) ]6 m6 a- [
{
: I1 \7 Y$ z- P; M( Q IWbemServices *pWbemServices = NULL;1 q4 W k2 N( }( D
WideString wsNamespace = (L"root\\cimv2");: g/ ^: K2 p7 ]" B
if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK) E: O3 Z) F4 ^9 Y+ ~* \ f; q
{ [2 T) H# E8 q4 ?9 p7 P, \# k1 H \
IEnumWbemClassObject *pEnumClassObject = NULL;+ a, o: b8 x4 |
WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;0 k& I/ r: T+ a7 a- j7 T# f3 f
if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)0 ?5 t% F0 A% y o- Z
{7 N7 I f2 x# _& h" L& p% p5 @
IWbemClassObject *pClassObject = NULL;
$ s/ F3 u1 P$ T5 C$ W0 g- z$ V ULONG uCount = 1, uReturned;
: t" c5 d! F* m if(pEnumClassObject->Reset() == S_OK)& ~/ P/ P' E9 c: G3 l
{
& @- H* M6 u0 ^: x, E int iEnumIdx = 0;
1 f* X5 v" Z i8 A2 i6 Z" v while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)4 l2 Y$ C( x c( D% q& [/ U7 Y
{
' O0 w% n1 A8 J$ h) T lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");- q3 p: y+ B3 N1 F
% D: }9 q% S5 c2 {! A
SAFEARRAY *pvNames = NULL;
# W9 {2 y' l. U0 ^1 e4 A$ B if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)* A1 Z' c- N. P: X4 N2 N
{+ T1 j- w/ R2 t# e. q4 d! O" F0 u
long vbl, vbu;
) C7 S: p- c# \, w3 \1 m SafeArrayGetLBound(pvNames, 1, &vbl);$ T$ i8 L+ b1 F) k0 v; |' X7 l
SafeArrayGetUBound(pvNames, 1, &vbu);: v/ s: M1 {) J, w% T' u) m
for(long idx=vbl; idx<=vbu; idx++)
. c& { e5 B7 L5 `) i# ~/ N {. J: a1 z! I- c& u8 u' v$ Q. C
long aidx = idx;- w: d5 |! Z6 I+ M/ r2 y
wchar_t *wsName = 0;) B+ @% B& x6 ?! S3 }
VARIANT vValue;& l( O3 B5 a) H
VariantInit(&vValue);
n, ?! w. u9 H1 O. f SafeArrayGetElement(pvNames, &aidx, &wsName); O+ W! Z9 g& n* w
b5 O: x- C6 t% @
BSTR bs = SysAllocString(wsName);3 R; |! e9 x* t0 d
HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);8 } [6 C: k9 x/ Y
SysFreeString(bs);
5 k5 [! I5 c/ [4 |4 N$ u' a
0 o0 L. W3 \' j' @8 R if(hRes == S_OK)
9 j, ?- b1 h6 W) w9 Q {
; {' E* E$ n: M! ~- O6 a3 O9 ? AnsiString s;7 M o# d) N' P, X1 m
Variant v = *(Variant*)&vValue;
4 c. s) t+ L9 y+ p if(v.IsArray())
9 |1 G3 \7 l0 t) A {: |! B6 w: J/ d ]6 `; [# r# Z
for(int i=v.ArrayLowBound(); i<=v.ArrayHighBound(); i++)
# i8 A9 @4 _- I% U5 ?3 n' @, N {3 |0 W( s+ O4 C8 {2 |; J; D |8 I
Variant a = v.GetElement(i);9 ?) g$ n) O2 a, P2 G; ~
if(!s.IsEmpty())
' f3 W. M6 l8 k" w- P/ ~" k2 X" {* l s+=", ";" I: r0 g& g) o
s+=VarToStr(a);
% l0 e0 c- H# g( ?! Y3 x' ^ }
2 u) [/ Y7 ?+ o. d( d! }' P }
$ A* i% r1 m" i else
4 _/ \1 X& \( r; E {
# e* _% C" F) N5 ` s = VarToStr(v);
' h9 Z. A/ V/ Q% Y. T }
( |$ b- D" ~8 e( t8 k0 d6 I lpList->Add(AnsiString(wsName)+"="+s);. y* R! @- k9 S$ R; \/ n2 t
}
1 \- I; J5 B7 o; y5 A) k
9 ]5 `9 H( S6 ?; h, ^ VariantClear(&vValue);; S) r$ \- R6 s, Z8 Z
SysFreeString(wsName);" P, z' H3 r7 ?$ Y
}4 ~' E4 t" b- D/ |" {
}: P. Q- d2 R; R; y% K! {
if(pvNames)SafeArrayDestroy(pvNames);+ _; H7 L# `+ S7 B, D: z( T
iEnumIdx++;. W. G9 p; e( |$ V) g2 [) e- y0 e
}; ]7 l; s/ r7 \. P( c& ^
}
5 d% c) o/ D l; g2 ~ if(pClassObject)pClassObject->Release();
& w, k. n: K4 Y }+ j$ ?1 i0 C5 {5 X, u y
if(pEnumClassObject)pEnumClassObject->Release();2 @7 P8 h8 Q6 A! p/ Q! D
}! y8 s P2 a }( r
if(pWbemServices)pWbemServices->Release();& `* y. \: W/ T4 Y1 u, J. O
}, b l( x) x5 Q
if(pWbemLocator)pWbemLocator->Release();$ P! P/ n! y" H: ~! E
}6 `$ r" j. ~. X+ g, q- B5 Z& \
//---------------------------------------------------------------------------# b" p; M1 p, O
$ ]0 \$ m+ a1 j0 b& `9 C+ H" z// 通过 WIN32_bios 获取 BIOS 信息:
+ S" X3 @: S+ U4 b/ q1 yvoid __fastcall TForm1::Button1Click(TObject *Sender)
% M. {' c; Y3 H. M: q2 v{
2 A1 q, x2 d n3 ]' [) ` Memo1->Lines->Add("================== [WIN32_bios] =================");) N5 ]) J( g2 |; z `) ?- h- ?, b
GetWmiInfo(Memo1->Lines, "WIN32_bios");
2 x+ l6 Q ?. A$ }1 E Memo1->Lines->Add("");
3 G0 H; O( N C/ T}
- `( b5 `% H5 }2 i3 Q) {+ C, C
( N+ l9 o) M; D) w5 c- W7 Z--------------------------------------------------------------------------------
) O# A! u$ z6 } G1 D8 R5 `8 o& I! q h5 H
WMI 可以访问的信息类型有:
9 ?* r P0 |9 c+ C% P/ j- S Win32_1394Controller) k0 {2 q) d9 k4 E2 q' C
Win32_BaseBoard H3 s3 }- L9 ` B
Win32_Battery- Q- n6 K, z% G1 y
Win32_BIOS( v8 |3 q2 Y/ `: r7 n+ X# _3 i
Win32_Bus7 ]) n4 u; O" P! Y+ M% m
Win32_CacheMemory- ^: A* k. }3 X! ?* V- d1 V3 i7 R
Win32_CDROMDrive! |8 K t, N) {/ c1 d6 b4 o
Win32_CurrentProbe6 w( V- P: G' W5 ]% I& s9 j
Win32_DesktopMonitor6 |; n4 r+ s. Z$ ?/ ^( m) U
Win32_DeviceMemoryAddress) c l5 t" x) V2 V2 e
Win32_DiskDrive5 `# I0 Z. y, y' F9 o
Win32_DisplayConfiguration
5 S5 P" I A7 R% _7 T2 z Win32_DisplayControllerConfiguration3 K/ A4 Z0 p5 ]" v+ Y( n' ?6 i1 {
Win32_DMAChannel v7 ]4 z. q7 ^" A4 b, W" O& X
Win32_Fan
) h# X+ l; S/ w/ y! u+ M& v4 O Win32_FloppyController1 O: e# E( f' B+ | W* [# O1 }. f
Win32_FloppyDrive4 G/ u* ~# r% o
Win32_HeatPipe9 g- ]2 C; v4 J _7 ]
Win32_IDEController1 I2 Q9 a& N, N, K$ x6 L' C
Win32_InfraredDevice
8 T7 w. p; m, {. o6 | Win32_IRQResource, M# T' |4 o3 i" n' j+ V) S
Win32_Keyboard
+ r6 o# R, {# l$ g# ~3 D: a Win32_MemoryArray
& s& G& ^! X1 G) W c2 Q# U Win32_MemoryDevice
4 b1 H1 }2 ]( D( Q Win32_MotherboardDevice4 e! l2 r+ O4 [* }( g" M6 j8 z) K2 ^
Win32_NetworkAdapter
6 w/ Z2 W. k3 _$ o8 T* w% I+ _1 { Win32_NetworkAdapterConfiguration
2 i* y C8 y' }$ a Win32_OnBoardDevice
, G" P( B- W1 l+ c3 @ Win32_ParallelPort
9 _8 n! |) G2 h' g* r Win32_PCMCIAController8 a* G" c6 O5 a5 m+ c6 Y6 l9 _# }3 e1 A
Win32_PhysicalMemory
6 ^: q L& i/ K Win32_PhysicalMemoryArray
8 Y+ |1 y1 Y9 C! `2 r" H Win32_PnPEntity, s# ]/ U; ?1 F4 b
Win32_PointingDevice# \. s; x) H8 {& g$ ~3 z
Win32_PortableBattery
. x4 J; y/ T' E* D Win32_PortConnector8 {. ^* i( n4 I8 _
Win32_PortResource6 a) K4 t% K, z- l
Win32_POTSModem' D, V$ i- }( C1 P0 ^0 Q& p
Win32_PowerManagementEvent
+ J( f4 O- \+ j" s) [% X Win32_Printer) A- j9 x6 j/ {/ ?$ b3 ?% @
Win32_PrinterConfiguration- |* g+ w" q0 `* B+ I- ]. g# N
Win32_PrintJob) ~* R8 e% ]4 I, g8 M
Win32_Processor" V; W- z( G4 U
Win32_Refrigeration, D6 i5 v' h s! s
Win32_SerialPort$ o; ]( [' k. D5 Z$ Q
Win32_SerialPortConfiguration/ a# R# A# ^$ ], |* W6 ^
Win32_SMBIOSMemory
/ |2 d# ]3 j0 ^- S) T Win32_SoundDevice H( e+ y b0 O
Win32_SystemEnclosure
" ^4 s8 P7 F: b9 O Win32_SystemMemoryResource
, f6 Q: s( `: x Win32_SystemSlot/ W: B9 x3 K7 s4 G
Win32_TapeDrive
3 V! ]) I( C( i; S; {1 k: q% S1 W Win32_TemperatureProbe
* F. k: [+ @( N, M; X. A) W Win32_UninterruptiblePowerSupply# ]( A7 B4 w- U0 ? }9 ^; h
Win32_USBController" r+ ]# `) ^8 `3 G9 {6 v
Win32_VideoConfiguration
% E, P" I- B. C3 J0 W% r$ k: u Win32_VideoController' Z) c0 B' h$ P- `5 @* s* A. B
Win32_VoltageProbe4 [# s" p' j% i/ {4 E2 K
# a6 t5 w: h2 q2 P4 _
以上类型(字符串值)通过前面写的函数 GetWmiInfo 可以得到相应的信息, 例如 GetWmiInfo(Memo1->Lines, "WIN32_bios"); |
|