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

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

[复制链接]
发表于 2005-5-22 17:04:00 | 显示全部楼层 |阅读模式
  Victor Chen, (C++ 爱好者)
/ a0 K7 B& K. k5 I0 D6 J
' Q! [- s+ l' k; o. P4 S  C: R* J! T/ o& n
--------------------------------------------------------------------------------' e% g" a; t' y1 B8 `  Y" v
WMI: Windows Management Instrumentation (Windows 管理工具)
# K# E7 t  E. i7 h   通过 WMI 可以获取主板、BIOS、磁盘、显卡、网络等几乎所有的系统信息。
) S6 W) V4 J7 C1 k   利用这个工具可以管理本地或客户端系统中几乎所有的信息。
5 b4 d2 j5 [  ^& F   很多网络管理工具都是基于WMI开发的。在 Windows NT/2000/XP/2003 都有这个工具, 在 Windows 98 里面可以选择安装这个工具。 ( Y7 k1 N5 k& `

$ b( Q3 P& s9 u% i( A0 |% o--------------------------------------------------------------------------------
+ b! O% n  T% }- pBCB 的 WMI 库文件 wbemuuid.lib 由本站提供, 包含在本页下面的程序源码下载里面7 b; C1 y$ h' @! D# v

% d  ?  h3 z% x  h5 ~- V6 ]- e7 G--------------------------------------------------------------------------------) u* L2 k3 Z% Q/ W4 {3 \
① 初始化 COM 接口:# j, f" W4 ?2 Q" m' g/ {* f
  访问 WMI, 必须先初始化 COM 接口, 在程序的一开始调用 CoInitialize(NULL); 初始化, 在结束时调用 CoUninitialize(); 释放资源。
+ `4 p. E7 w9 x9 C9 O* e6 b9 f   这两个函数在 #include <comdef.h> 里面定义。
9 t) y# \# s3 G: y: c; c
0 I! C3 Q' `) S) q+ f6 l$ R+ _# E7 ?3 J② 获取访问 WMI 权限:
+ S/ m" Y7 k8 b8 G   CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);' `# F* Q- g+ v- F
  如果这个函数返回 S_OK 获取权限成功, 否则为失败。, E3 x" b5 l( F6 e) i4 ]

* |8 V) f$ D: T2 y③ 通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息:
. g3 x8 Y% y0 t; }   这个函数的参数: lpList 返回信息, wsClass 为要查找的系统信息类, 这些 COM 接口在 #include <wbemidl.h> 里定义。
: t0 r8 U2 b0 Q
4 t( A1 U' j3 E) w- i1 I' T* dvoid GetWmiInfo(TStrings *lpList, WideString wsClass)# @8 \- l0 p3 i' u& a# D; a" s
{' k8 W4 z% K; b! I
  IWbemLocator *pWbemLocator = NULL;8 t0 G1 G9 d% K9 J/ y' i
  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)
+ z5 r' D: R5 H7 J4 A! t7 S   {
  b1 h9 T0 z- d5 S2 N% n     IWbemServices *pWbemServices = NULL;
( a" L) w( W3 l- F% ^/ j$ y     WideString wsNamespace = (L"root\\cimv2");
/ q% x5 s9 ~" `8 O+ M     if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)
: \5 o7 A5 Y; w/ S" f+ o; P$ q      {
, s* z3 ?6 a4 x+ e/ h        IEnumWbemClassObject *pEnumClassObject = NULL;3 n5 L' g; T- }, T" k
       WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;  @1 m+ {# b8 C$ }# r+ \: N
       if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)' Q9 C" N( w0 ^# }! ~
        {: I4 e2 m! Z+ o% C8 A, x
          IWbemClassObject *pClassObject = NULL;
- q$ _0 q' u* b% F/ E! `2 }* \9 Z           ULONG uCount = 1, uReturned;
# ^) {8 I! v/ ^6 r           if(pEnumClassObject->Reset() == S_OK)% K( U8 L" e- _/ s2 W9 |3 f9 c
           {
3 d6 m# _& g4 J- y: R              int iEnumIdx = 0;
* k- Q( b4 g6 ?( U: Q& J              while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)9 {8 M! E: [3 _
              {
' y3 @; ^$ Z2 p1 A' r3 m* q/ ?                 lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");
( D/ }2 S1 Z/ T/ q
* c. T- J0 E8 u- B8 L6 R                 SAFEARRAY *pvNames = NULL;# N" I: E! }6 J) c5 [  ]; M+ X
                if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)
5 n6 A* \- A+ r; j3 `                  {+ k/ E1 ?* R& F) h. O( i' S
                   long vbl, vbu;
; c0 C- @+ C% F& ?) D                    SafeArrayGetLBound(pvNames, 1, &vbl);
: k0 a1 G: W+ J4 Y  H: p                    SafeArrayGetUBound(pvNames, 1, &vbu);" ]4 T. o7 T5 b& u  Q, H4 I
                   for(long idx=vbl; idx<=vbu; idx++)
5 }$ x/ l+ X$ X  r# Y                     {
: o' j" X3 d8 m7 t7 T( ~                       long aidx = idx;- @4 D; N! O% Q' J' E
                      wchar_t *wsName = 0;. {- |: R' w% {5 I; M" [4 p: k
                      VARIANT vValue;
9 `* ?/ P/ y, @$ f! s8 N' o                       VariantInit(&vValue);
( t% S9 L+ m% f, ~* Q$ b                       SafeArrayGetElement(pvNames, &aidx, &wsName);
8 M' A5 H: u* E: Y8 W
$ ~' T+ y! ]8 R* r& H$ I: b8 Z                       BSTR bs = SysAllocString(wsName);
& F3 F1 c. }; \$ L                       HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);" m/ @# w4 k5 s
                      SysFreeString(bs);
& X2 i, h9 K0 l" |8 t
( j1 `- j: m9 M9 u                       if(hRes == S_OK)0 i9 z- [6 q% y! o& [
                       {
% ?' D- r7 l) t$ C( r/ i                          AnsiString s;
+ D/ }" j" K* R! A                          Variant v = *(Variant*)&vValue;- t6 c% J; y6 B! s
                         if(v.IsArray())
2 o' x" C' i$ \6 m& K                           {. O( h" Y: T& O3 t3 I: s3 L+ O: c8 c
                            for(int i=v.ArrayLowBound(); i<=v.ArrayHighBound(); i++)5 }3 Y- s/ k! m* i$ ?
                             {
* {- U/ I; v& Z( g" ~! W4 Q                                Variant a = v.GetElement(i);; l# o, s& W6 k5 T$ J
                               if(!s.IsEmpty())
7 E3 m2 Q0 g1 x3 d8 u5 K. k                                  s+=", ";  J$ A/ r5 \, g8 H
                               s+=VarToStr(a);
; w6 |! {3 B9 C( z4 u" l$ X                              }% c% R, z3 R' D8 n
                          }) d: b* o: S' |" @! Y* ]! \- ]3 M
                         else; R& b, j( h. L& P2 L
                          {
  i3 }! w) J! n                             s = VarToStr(v);" h4 A' i+ N5 n$ y% m( O4 n
                          }. r+ y' z. O; x
                         lpList->Add(AnsiString(wsName)+"="+s);6 w2 ?8 P; F# N$ Z2 B. s
                       }
5 _4 X" ]4 o4 O
) C9 d3 b- I" A                       VariantClear(&vValue);
2 T" I* o& e; n% t9 r$ n" n                       SysFreeString(wsName);
/ q+ O8 Z: B& A+ }( @! C                     }
$ e$ C' l9 G5 j6 ~1 V5 a7 {- s- f                  }
3 ~1 Y. F. F7 d' {/ \: ^                 if(pvNames)SafeArrayDestroy(pvNames);
  c+ x$ {$ r1 d5 }6 R, X3 l                 iEnumIdx++;
) D: ^# Z( A* r7 K               }
% Z6 W: Q% c1 B6 n3 S0 F6 R* Y9 w            }+ i' X& k5 M% R8 v+ p
          if(pClassObject)pClassObject->Release();
. s! `% E, I' y: D5 A         }. g+ E- {$ c9 ~$ u% d
       if(pEnumClassObject)pEnumClassObject->Release();
( H) G$ w3 T0 h7 s; Y+ r1 }      }9 ]) ~% T: k4 `, J1 e
    if(pWbemServices)pWbemServices->Release();
: I/ o; s. n2 L% U5 e   }
5 S- P/ J6 @- ?8 N: x# I  if(pWbemLocator)pWbemLocator->Release();
5 |8 y8 K  R0 s% \  q# I3 r}' n* j3 v( n: E. s9 ]; B9 B/ D$ J+ O
//---------------------------------------------------------------------------, }; S+ T/ [' X' S$ p
0 ?3 j" I, L2 s0 o) Z1 N
// 通过 WIN32_bios 获取 BIOS 信息:( y. @$ T( O) o" N5 k& d
void __fastcall TForm1::Button1Click(TObject *Sender)
  b% z% m/ s: n, ?  ]# l# ]0 A{  L( t& Q3 Y8 r, g6 N+ a. x
   Memo1->Lines->Add("================== [WIN32_bios] =================");
' U7 o9 u6 W: X    GetWmiInfo(Memo1->Lines, "WIN32_bios");5 B) S2 p3 z" p6 |5 Z
   Memo1->Lines->Add("");  K+ @1 t+ X$ p5 t' n- T/ W
}, S$ c* }& j: U; C- ^  p0 ^

$ U( s7 u+ {: I% ^% `% H# g--------------------------------------------------------------------------------/ x5 t  F, q2 P. N& D$ |
& Z) i  D' J5 R
WMI 可以访问的信息类型有:
! r3 Y: t) ~, y" x4 z   Win32_1394Controller# ]- i+ p# q6 k, W
  Win32_BaseBoard
1 A( G. }, f0 w! \- x. V   Win32_Battery' r, O/ P( l* Z) C8 _3 b
  Win32_BIOS
' z4 S! L4 C: @   Win32_Bus
% ]  ]! t; p' C6 b   Win32_CacheMemory% z: T( X8 x: K8 B3 b6 X
  Win32_CDROMDrive
: {7 H* j! d: w/ [7 D5 K) t   Win32_CurrentProbe
$ Q( d5 Q9 n) e# c9 r. o3 l) m: X* C2 E: \   Win32_DesktopMonitor
: O7 ^2 Y/ p( w5 K; U" @& V   Win32_DeviceMemoryAddress
' o) O; _. k0 w# _- N. N* t   Win32_DiskDrive
4 {; p  g) m1 F  [/ s! i! m   Win32_DisplayConfiguration
1 F- L7 Y2 N2 X/ v( Y5 n   Win32_DisplayControllerConfiguration
) {! a6 K' }5 }5 D  L' g5 E9 T   Win32_DMAChannel
# c5 F; I6 e% X8 `( w   Win32_Fan
4 I" I5 I- ~1 k, r$ g# C6 S   Win32_FloppyController
' t/ x8 r8 n  {/ t* U$ x' W% \   Win32_FloppyDrive2 Z0 `( ~$ Q0 S1 S5 m
  Win32_HeatPipe" D' k4 Q  r2 ]. l2 i' N/ F5 s8 {
  Win32_IDEController& Z4 s% {( f- w  U' s1 ]+ Z
  Win32_InfraredDevice: \/ l. i  F! K" P' P* D% g
  Win32_IRQResource  `6 K3 @- K" G; t: O  n
  Win32_Keyboard
, |. B4 D; r) T& X2 E9 h  B   Win32_MemoryArray
- f( W3 ^, M5 Y! K, @   Win32_MemoryDevice( y  k+ }/ ^- {7 D7 |0 e
  Win32_MotherboardDevice
3 O* @1 O1 K  R& e; T5 E( g   Win32_NetworkAdapter, `2 n: [7 e' x  w# M; C
  Win32_NetworkAdapterConfiguration+ p, I" \5 u8 j$ U# J: ^2 A
  Win32_OnBoardDevice2 K# n! n+ ?2 W/ ^; S* d
  Win32_ParallelPort
4 C8 E$ I! ]/ ]; K- J* d   Win32_PCMCIAController) x) ~7 N& }6 g, V1 C. @
  Win32_PhysicalMemory
% a4 x% d: p0 v2 S+ f1 e, F: v- I   Win32_PhysicalMemoryArray3 n+ P9 R/ w" |, y/ ]
  Win32_PnPEntity
: R( _' V# l- T# b) @   Win32_PointingDevice; L" ?( b0 Y, K4 q+ c
  Win32_PortableBattery
3 s2 F2 U6 O' M8 U8 q   Win32_PortConnector
. o- J2 k6 S2 u) {# z2 B1 `( r. K   Win32_PortResource
* J; Y8 F- A$ [' W$ |5 M  n   Win32_POTSModem4 }4 S- ]* q! p; d/ Z% S& Q
  Win32_PowerManagementEvent
) R/ \( i/ n6 Q* R   Win32_Printer0 J! u8 e% x1 g6 U1 N# q
  Win32_PrinterConfiguration
4 C! F4 @1 O) |" {   Win32_PrintJob
! E. ^4 E3 Q6 H2 ?' e1 O4 O- N; ^   Win32_Processor1 K& w) P& _4 C4 r1 `6 l7 |& e
  Win32_Refrigeration
; ^  g9 B; O3 k* c( m. m, I$ h   Win32_SerialPort
3 R/ V. e- D  |   Win32_SerialPortConfiguration
- }) P7 s+ i  E* u4 \, g   Win32_SMBIOSMemory' I" y. x. l2 q  K/ ]# r
  Win32_SoundDevice5 {5 b% K- W% P# G8 ^! _% M
  Win32_SystemEnclosure& u7 d& x, P: |0 z3 _' S5 h  S$ K: G
  Win32_SystemMemoryResource
& }1 }5 y& S2 N6 m& u  F2 o9 M   Win32_SystemSlot
8 M& S% w0 U/ d4 X. z6 r: g; S$ |! @   Win32_TapeDrive
1 X7 x7 L. ?1 I/ r/ m   Win32_TemperatureProbe
3 @. c! `0 x& j   Win32_UninterruptiblePowerSupply
( r, r; P, f  E, ^7 V% j   Win32_USBController
5 J2 P, b% V9 {& P( U, ~   Win32_VideoConfiguration
" U+ ~  G% B9 Z7 n   Win32_VideoController( c  e0 L! e: V! C; d& T
  Win32_VoltageProbe
# ]2 G9 Y: {8 D. F1 U' E* g  \; N4 G7 E; u4 v/ y& v) o+ z) O
以上类型(字符串值)通过前面写的函数 GetWmiInfo 可以得到相应的信息, 例如 GetWmiInfo(Memo1->Lines, "WIN32_bios");
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-2-3 14:20 , Processed in 0.019738 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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