找回密码
 注册
搜索
查看: 12406|回复: 0

[收藏]C++ Builder 通过 WMI 获取系统信息

[复制链接]
发表于 2005-5-22 17:04:00 | 显示全部楼层 |阅读模式
  Victor Chen, (C++ 爱好者)* X" t5 S8 ?0 x. t9 X
, H5 I) v$ z3 w9 k6 \* n4 L
& a' b' D$ L8 E; T- X+ w9 d# R
--------------------------------------------------------------------------------. F( u3 m3 ^/ @0 w/ R7 _! `4 c* L
WMI: Windows Management Instrumentation (Windows 管理工具)- A1 @$ J8 W; U$ d' ]  j3 Z
  通过 WMI 可以获取主板、BIOS、磁盘、显卡、网络等几乎所有的系统信息。 1 l) ^0 |$ h1 l. [
  利用这个工具可以管理本地或客户端系统中几乎所有的信息。
# c- i+ o! O: r# V' n9 v2 E% }   很多网络管理工具都是基于WMI开发的。在 Windows NT/2000/XP/2003 都有这个工具, 在 Windows 98 里面可以选择安装这个工具。
& r8 n" a# a- B( q4 x. L8 Y; y3 {( k% M: U6 Y
--------------------------------------------------------------------------------
- w. s9 A% M8 d/ T- M) x( U6 FBCB 的 WMI 库文件 wbemuuid.lib 由本站提供, 包含在本页下面的程序源码下载里面
' {% C' S2 [/ s+ t0 v5 C# ]
' W( X  A3 n1 J# [- R7 j--------------------------------------------------------------------------------, }# f2 }7 k0 J3 p7 t2 b7 s+ G( b
① 初始化 COM 接口:
- V' }2 J/ t1 J   访问 WMI, 必须先初始化 COM 接口, 在程序的一开始调用 CoInitialize(NULL); 初始化, 在结束时调用 CoUninitialize(); 释放资源。. X. e. ]9 E$ D. f2 a( c1 W
  这两个函数在 #include <comdef.h> 里面定义。5 s$ m& x5 A6 }% F# B
7 t9 b' s# l3 |8 c/ |6 u
② 获取访问 WMI 权限:
; v, F  a6 [+ P$ j   CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);
- p8 C4 D5 E" r# ?8 g   如果这个函数返回 S_OK 获取权限成功, 否则为失败。
+ O9 W8 h# A. W
. g' ^% r/ r$ g6 B9 Q1 D7 R③ 通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息:) f) z# w- j" G; w* E/ s# O" Z
  这个函数的参数: lpList 返回信息, wsClass 为要查找的系统信息类, 这些 COM 接口在 #include <wbemidl.h> 里定义。3 }) `+ m5 C0 c
6 B' y% ?9 `. A0 g3 x5 G% s
void GetWmiInfo(TStrings *lpList, WideString wsClass); }/ }6 c3 x* s& s0 ~
{
7 M( Z, i# P) Q% p* @( T  IWbemLocator *pWbemLocator = NULL;' V5 ?; D6 W" T& r
  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)
4 L) Z. H  D( y& m/ D+ t. h   {! n; ?0 w2 P1 z$ Z" N
    IWbemServices *pWbemServices = NULL;2 m, \0 _, W" b
    WideString wsNamespace = (L"root\\cimv2");
+ C' H* x- L9 a' ], J     if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)* ~0 l2 ^8 o, l' i+ K6 W
     {# B& U9 l5 Y$ c$ @$ m7 o; G; \3 ]
       IEnumWbemClassObject *pEnumClassObject = NULL;
. ?: j; i  W. k+ k! l        WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;; Y0 ]7 o( Y6 t% }& _$ E2 o+ _
       if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)
4 m# _7 I- L, k  H" M& \         {
: v9 A( P5 \8 H' j; |0 E           IWbemClassObject *pClassObject = NULL;
0 P5 w0 F0 s5 I) p- M+ Q* ?1 ?           ULONG uCount = 1, uReturned;' u9 e) f, L. S
          if(pEnumClassObject->Reset() == S_OK)
0 T! W( k0 Y2 X6 y# P% c            {
3 G: V/ P$ i6 |; ]. s8 Z              int iEnumIdx = 0;6 n- {) q& |1 c  }" G$ s
             while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)4 n& Q- j/ i/ G6 D) S) I  t
              {
( L$ u) f4 ]) V7 ^/ h- a                 lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");
4 o5 P; R5 A- \+ S% s
* F' m5 r1 S. k( @                 SAFEARRAY *pvNames = NULL;" X$ f( K* U4 P5 g+ C$ @, v
                if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)4 U% w$ |0 m* i" W( r" y0 h
                 {$ g* u4 d# u5 a5 y& `; g
                   long vbl, vbu;
0 t3 z. N& I2 s- v: j$ P5 X' m( y" G                    SafeArrayGetLBound(pvNames, 1, &vbl);" {; \6 l" f1 x& o
                   SafeArrayGetUBound(pvNames, 1, &vbu);. Y+ d" [8 i/ U4 t4 S. `& }
                   for(long idx=vbl; idx<=vbu; idx++)) v$ p5 `( ]/ q- v7 ^  `6 {6 F
                    {
& C3 P! z# C. A; f, g3 y6 B                       long aidx = idx;" S" r8 a3 L! y* r8 {
                      wchar_t *wsName = 0;
' e6 X2 J9 J' Z1 n" k% A2 o  W8 a                       VARIANT vValue;, ?8 f. y, g/ U3 S: Y2 J
                      VariantInit(&vValue);
/ n! z! g8 J4 o) k  p                       SafeArrayGetElement(pvNames, &aidx, &wsName);
8 t3 i% D+ a0 j+ A2 n$ y: @- O& x# m9 |
                      BSTR bs = SysAllocString(wsName);
& U& }! k$ p# W" S* v- d                       HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);
$ z" n( @0 Q( e5 c. u0 o; \/ c- r                       SysFreeString(bs);  @* P. ]! B, q) L
0 b9 x: O8 t4 K' m' T
                      if(hRes == S_OK)
0 p4 f. V, t  j  {: m7 k7 U                        {' R6 Q1 x& a) ?  Q5 J
                         AnsiString s;
7 k2 E3 C: S) ^. H* I; m% z9 p' O                          Variant v = *(Variant*)&vValue;
$ ?) @) t# f. |$ t0 x                          if(v.IsArray())( M/ P$ `1 I# G( H
                          {
* A" a) Q/ Y: ]5 u2 P1 p2 J                             for(int i=v.ArrayLowBound(); i<=v.ArrayHighBound(); i++)
2 \) N4 s# u) V. H                              {
6 @' M4 A( `2 ^- }2 s$ j# |# V8 h                                Variant a = v.GetElement(i);+ i' z0 v" o6 K2 H8 ]' F5 z
                               if(!s.IsEmpty())
9 ?1 `: N5 `+ j/ W8 |                                  s+=", ";, j1 B* z0 @6 n/ K4 Y/ g* U
                               s+=VarToStr(a);
3 X4 T! h- h/ L9 V' p5 e                              }
1 e6 I1 m, X+ ^% g( U                           }
8 }2 \# a1 b2 S. D( w8 X$ @                          else
. H9 n$ Y* b7 `+ P' T                           {3 [/ c% p9 i) U  I
                            s = VarToStr(v);
/ ]+ ]- F: R, y* _' Q0 r4 C* O                           }
" D% ~' A4 n5 b% X" v9 a! f                          lpList->Add(AnsiString(wsName)+"="+s);
4 a- W( e9 m! B2 T0 W0 f                        }
- B5 `2 S  V0 n% D
7 |7 m6 o  q" e% T                       VariantClear(&vValue);; C( _  S9 c  l2 ^$ F- Z5 G
                      SysFreeString(wsName);
) W! J' o% S! K: o! N" s3 @7 {                     }8 A# O$ m/ y# z9 g' E' T
                 }) z- c7 f0 C  R( }+ [% ^( k
                if(pvNames)SafeArrayDestroy(pvNames);5 L; j( q8 l; F# A) r% B
                iEnumIdx++;& n" K) @/ G0 g9 \; e$ o
              }
. ^1 {4 d7 ?! f- U- X            }" ]1 r# `9 r3 D, O
          if(pClassObject)pClassObject->Release();* l" h+ `6 _( B
        }
" W4 e6 F# {% V5 u/ i        if(pEnumClassObject)pEnumClassObject->Release();$ {$ ?; x8 F  P5 \
     }
$ N) M8 j) C8 B0 U& T$ H7 ^     if(pWbemServices)pWbemServices->Release();5 Y2 F" N$ r7 U9 d  X1 i* O3 E( p
  }! s. E9 G) X6 ]' B9 W3 N/ O
  if(pWbemLocator)pWbemLocator->Release();
3 \0 s% P  a. l! {1 H+ ^4 j}
+ q0 c% V; R: n- w. B  S//---------------------------------------------------------------------------3 P4 I. `3 K# r
& X- m1 R3 L6 y2 [/ y
// 通过 WIN32_bios 获取 BIOS 信息:* K( [* t( D2 |& Z% Y- o/ V
void __fastcall TForm1::Button1Click(TObject *Sender)
7 V3 v4 E) i: b8 C{0 P6 k! G$ U5 n6 _$ [- w& R/ {+ u
   Memo1->Lines->Add("================== [WIN32_bios] =================");
. q! ^; R6 ?8 `    GetWmiInfo(Memo1->Lines, "WIN32_bios");
0 d  u7 n$ d! [) n- C) p    Memo1->Lines->Add("");
7 J% ^6 a, a) f) M8 s. N3 @+ M}
7 ]9 o( Q( f* k/ m- k. B  o
$ m3 L$ H: n6 E& N, X3 w--------------------------------------------------------------------------------! a1 r7 p/ R+ f* ]1 U  ?

; S( P2 q) s7 SWMI 可以访问的信息类型有:
9 B& U5 i/ R+ y0 X6 w! I" m   Win32_1394Controller
& U& }1 ?  j1 x5 ]6 Z   Win32_BaseBoard
0 f* p" ^5 f. A   Win32_Battery6 k. o' G) @& W
  Win32_BIOS
0 R, b" s( M/ e5 c4 [  Z* E% P   Win32_Bus
$ M3 B$ h  O& ?  E/ Y   Win32_CacheMemory6 l( i! R: [( k& _; X: L
  Win32_CDROMDrive7 f0 I6 T# @1 A+ D' w4 o
  Win32_CurrentProbe/ j: N8 d' y- \1 y3 D5 c! Z  A
  Win32_DesktopMonitor% {. M1 _2 K3 l4 v" k
  Win32_DeviceMemoryAddress
- r+ _2 w% B2 b, V6 @( J. q+ p   Win32_DiskDrive
, R  C+ u' R% L* |1 |   Win32_DisplayConfiguration
  V* |& h! ^1 W# s9 D* C$ v& l   Win32_DisplayControllerConfiguration
( u, }8 p# J1 K1 n( M   Win32_DMAChannel
7 H0 {# n: x7 t. G4 V   Win32_Fan
7 G; [) G! i0 m" W" I" Z   Win32_FloppyController
0 D! Z, {& H+ n   Win32_FloppyDrive
% b7 m' I6 j4 }& {$ a! t   Win32_HeatPipe& b, s% [, I0 R7 P1 a
  Win32_IDEController
& z" p' O+ m8 K8 m! H% X' j+ \   Win32_InfraredDevice
, |6 h: t6 V( u2 H, z0 ^0 Q   Win32_IRQResource  [% b3 x) x6 V* |9 f  n
  Win32_Keyboard+ ]5 U  N$ m7 F/ I0 u- U6 \% K
  Win32_MemoryArray1 |6 d3 M9 E4 Z; b) V
  Win32_MemoryDevice4 B, Q0 Q; Q- R& ]; [1 d* E
  Win32_MotherboardDevice8 U8 O9 ]! B( U) G
  Win32_NetworkAdapter
  E$ V3 I$ D. C. W! N# k   Win32_NetworkAdapterConfiguration7 }8 F7 I# N- T7 u- {
  Win32_OnBoardDevice/ X3 k6 }! }& ^/ X
  Win32_ParallelPort" m+ G9 D# K1 _
  Win32_PCMCIAController
. o7 R9 ~  E# y( y/ J   Win32_PhysicalMemory
; b$ ~7 I, Q' E6 k$ z; _! U. T   Win32_PhysicalMemoryArray) f' o3 K/ g6 I/ ?" S/ C# N
  Win32_PnPEntity: ~$ P( `" d0 \! O0 r4 k
  Win32_PointingDevice
8 Z' t5 N- A; I# g0 N( B0 r   Win32_PortableBattery, A8 g, p" Z& b* S" `0 a2 s0 j& `
  Win32_PortConnector5 p* |/ g7 `; h: L( V5 Q
  Win32_PortResource
* p% f' \. W5 F& H* T   Win32_POTSModem7 k4 y$ F! D6 R2 V3 D2 @
  Win32_PowerManagementEvent
9 ?" E# R3 O1 x5 X+ w5 U8 a   Win32_Printer
8 V- _; ^: F. Y3 i   Win32_PrinterConfiguration
$ i- O* _4 I/ V* n2 w0 l5 J$ Y   Win32_PrintJob3 u8 D! y' f6 o1 P: t
  Win32_Processor
2 E9 K5 }; E& [3 t4 a" q& Q: s   Win32_Refrigeration
% V# X( V' D0 G1 e7 _5 |   Win32_SerialPort
& R0 G: ]  j6 n  d* \   Win32_SerialPortConfiguration! v7 ~7 L" u& A/ Q
  Win32_SMBIOSMemory$ t! H4 ~( `/ q/ b. q8 p, q
  Win32_SoundDevice
! T( d- F2 m9 J8 z9 p# A; n   Win32_SystemEnclosure4 Z* b( ^! g5 |( i7 d/ s# v
  Win32_SystemMemoryResource# u/ g1 t/ ^  t! A
  Win32_SystemSlot2 a$ t3 ^4 M) c# y! l
  Win32_TapeDrive
2 e  _4 \( s; f. W   Win32_TemperatureProbe
0 n, J/ t0 N) a( G! P1 _   Win32_UninterruptiblePowerSupply  h6 g7 `+ }7 W! A5 f8 h4 F5 W: s
  Win32_USBController
. M. q* _2 ]! w; C   Win32_VideoConfiguration4 G: |- A. v3 i3 H: ~# \
  Win32_VideoController
3 d/ j6 m' M  ~% x6 C8 v& M2 G0 ]# S   Win32_VoltageProbe7 \0 U) h$ |& d8 p

- t3 \2 r, h/ n/ x# b( y( |9 g" F以上类型(字符串值)通过前面写的函数 GetWmiInfo 可以得到相应的信息, 例如 GetWmiInfo(Memo1->Lines, "WIN32_bios");
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|宁德市腾云网络科技有限公司 ( 闽ICP备2022007940号-5|闽公网安备 35092202000206号 )

GMT+8, 2025-10-24 07:03 , Processed in 0.045864 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表