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

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

[复制链接]
发表于 2005-5-22 17:04:00 | 显示全部楼层 |阅读模式
  Victor Chen, (C++ 爱好者)' S+ d0 A% [- s# n9 s' ]3 N$ {

! v5 c0 T4 H0 _& b7 ?# P! O; J( V+ k3 J) X$ Y- o& g8 _, s9 S
--------------------------------------------------------------------------------: ?& g; }9 I$ ]. Y
WMI: Windows Management Instrumentation (Windows 管理工具)1 S7 i* O3 ~1 `1 Q  o9 {
  通过 WMI 可以获取主板、BIOS、磁盘、显卡、网络等几乎所有的系统信息。 9 S: [' K& v# H* f( ?" Z( g% g
  利用这个工具可以管理本地或客户端系统中几乎所有的信息。
2 x2 o0 ]3 f; f2 h; r9 `   很多网络管理工具都是基于WMI开发的。在 Windows NT/2000/XP/2003 都有这个工具, 在 Windows 98 里面可以选择安装这个工具。 8 x9 c. J0 i7 u: M8 P
% O* L0 v, _$ s6 S  n
--------------------------------------------------------------------------------4 o" R% _8 C5 o2 b* y/ x- |. p
BCB 的 WMI 库文件 wbemuuid.lib 由本站提供, 包含在本页下面的程序源码下载里面6 q8 C  ~$ K" o8 ~) c
1 P4 s9 z/ D  e' A" G
--------------------------------------------------------------------------------( F( {' G. t8 o5 G" `& n" ^4 `1 o
① 初始化 COM 接口:3 y3 h# p7 |6 p
  访问 WMI, 必须先初始化 COM 接口, 在程序的一开始调用 CoInitialize(NULL); 初始化, 在结束时调用 CoUninitialize(); 释放资源。
, f1 S; |! W& R7 Y9 l  Z/ o8 B   这两个函数在 #include <comdef.h> 里面定义。. p4 c5 Z: D6 `. e
! z* W& |5 J3 t: t9 t# r
② 获取访问 WMI 权限:7 T& t4 f0 @, v# t
  CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);
9 s9 V' [7 ]5 l& m   如果这个函数返回 S_OK 获取权限成功, 否则为失败。5 i7 k  i1 `) b9 A1 z

7 @  x5 K1 ~/ A5 d4 `& a* N& A③ 通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息:5 a  C* W! u) y5 W1 w( b* G, m& f# C
  这个函数的参数: lpList 返回信息, wsClass 为要查找的系统信息类, 这些 COM 接口在 #include <wbemidl.h> 里定义。
3 W0 F( W; K9 s, R  \6 H; B0 F3 p2 J# u' w% l. n- F" W: q
void GetWmiInfo(TStrings *lpList, WideString wsClass)/ s, ]; e( ^7 m7 e& n
{( m# R: p$ Z# v2 }' E. P
  IWbemLocator *pWbemLocator = NULL;
8 G4 O$ x7 h3 s4 G" W( g- V  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)% n6 w. v8 C( j( q# O0 b
  {
* b8 ?2 ^4 |. U" O. y' G" {1 ~3 `% M     IWbemServices *pWbemServices = NULL;9 l5 Y& x0 Y4 q& j* B
    WideString wsNamespace = (L"root\\cimv2");* \8 V$ k& k* t8 C
    if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)
. Y6 `: S4 S* k' i* E9 T& F      {
; a; O" z2 R) }# Q        IEnumWbemClassObject *pEnumClassObject = NULL;% H0 a3 j% P; L  U
       WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;8 T3 n) X$ q: \  {" X: {0 j
       if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)8 w8 g% d. y# R- S6 a: E
        {( l- A0 M  q0 e! N' q
          IWbemClassObject *pClassObject = NULL;
3 p8 Y- f% x' n7 K! i           ULONG uCount = 1, uReturned;
6 X( Z+ L% F# b+ r0 W9 J) L% |           if(pEnumClassObject->Reset() == S_OK)) N6 V9 B4 |1 Y* r) P; Z
           {
3 }& \+ ?7 P6 Y              int iEnumIdx = 0;- u: P) `/ ?, T/ p* ~7 N+ x
             while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)- \! P$ f1 q/ E
              {
( w4 E- G. C2 C" q9 e$ E! o' B                 lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");
3 X. |0 |& B4 e! d: |* U
/ h9 G; n1 z" H2 D2 L                 SAFEARRAY *pvNames = NULL;1 B3 g6 g5 r- C4 w
                if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)
; O! t6 e% f. @7 d% m- |                  {
% ~, k' G0 F+ y5 P/ _, {+ t: T                    long vbl, vbu;7 M& K' n- x3 N
                   SafeArrayGetLBound(pvNames, 1, &vbl);
; C; D1 T* U) [* i                    SafeArrayGetUBound(pvNames, 1, &vbu);/ ]7 y$ s3 W/ l
                   for(long idx=vbl; idx<=vbu; idx++)7 W5 b# y" I2 \5 [: p$ k" l  ~
                    {2 k& v/ W& S8 Y1 e/ V- @6 A
                      long aidx = idx;, I, V1 Y- t5 S6 K; j5 h
                      wchar_t *wsName = 0;7 m# E' Q: F( P8 E9 C; R7 w/ h
                      VARIANT vValue;6 C* ]: s9 m2 e1 v2 q
                      VariantInit(&vValue);( z, q* A+ i3 t  S2 c
                      SafeArrayGetElement(pvNames, &aidx, &wsName);( o( ~$ X% D& @7 W4 [' ?$ z
! p3 a) X* e. l% I
                      BSTR bs = SysAllocString(wsName);5 v9 K" }$ H! V/ {' v
                      HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);2 k  Q) a+ F! W2 u  `3 a$ b8 K
                      SysFreeString(bs);7 L2 f& w! {: ]# Q0 |6 h
  w5 \7 x' @* ^% ^2 R6 M
                      if(hRes == S_OK)1 y$ z4 u6 V2 ^' g
                       {5 s# k/ g2 h2 K& x7 ]% B; k$ a5 q  }
                         AnsiString s;
8 G) F9 Q5 @( R" _: j                          Variant v = *(Variant*)&vValue;+ O4 }# ^6 }- J1 u. t) V3 q
                         if(v.IsArray())
- `+ e, g# L+ I0 h: {$ Q& F                           {! j& W2 a+ e9 j- s$ F
                            for(int i=v.ArrayLowBound(); i<=v.ArrayHighBound(); i++)* T0 c" E' Y+ B) `
                             {
  Z7 q' S4 ^  g9 X                                Variant a = v.GetElement(i);
7 I) i( p: h) _0 s- Q                                if(!s.IsEmpty())
( ?% x# y! M9 N! g2 _& O                                  s+=", ";
8 ^- {  s! S9 Y( {" E1 R                                s+=VarToStr(a);. x/ G, F4 d# l2 [
                             }' h/ t2 P9 y! K3 q$ g: q0 ]8 g
                          }
- t, w8 ^; r% g' h/ |" v" [                          else, x8 t2 X- F: O( _& s6 \% b
                          {
; u/ Q. }) B7 ?# a# s                             s = VarToStr(v);8 x, S! [4 \0 b/ _$ [7 e' l0 X. C
                          }
, k4 Q. P8 L; j2 M                          lpList->Add(AnsiString(wsName)+"="+s);
" R7 @( o% K" X( q                        }) U- [! x# r1 m$ ^% o* z- G3 v* N
3 _% Y6 }$ h/ x" O" ]- ~
                      VariantClear(&vValue);9 m% t7 x+ x% c& k, o
                      SysFreeString(wsName);2 _6 q/ F5 }) s# s+ m+ y
                    }
5 ^* h% M7 L8 M: w' A* n                  }
* `( A4 e0 a9 @5 m, U4 i                 if(pvNames)SafeArrayDestroy(pvNames);
7 d9 Z& r7 X# }6 y                 iEnumIdx++;* o% n# K5 l" {9 X+ P( C
              }6 R6 K9 x: W9 d; V4 Q% W9 W8 h2 F4 J
           }; y. u# j9 q( m+ E/ K
          if(pClassObject)pClassObject->Release();
' A# U- e* C( w5 p         }
* n2 N- ^0 C& a0 Z' S) S2 m9 |  v        if(pEnumClassObject)pEnumClassObject->Release();* }) _# U6 ?! f, ~! l' Z  p7 ~
     }0 H9 ?& _9 _  ^+ c( c  K7 Z
    if(pWbemServices)pWbemServices->Release();6 S  K" W3 |* o8 W5 S! g1 j: ~
  }
7 b: n9 |+ R! _0 H+ @0 N6 m  if(pWbemLocator)pWbemLocator->Release();* \( |, `1 n" G
}1 C7 Q% h, ?8 D6 {$ I$ Q) K3 N
//---------------------------------------------------------------------------
2 t% J3 I. [8 b; n$ T9 b4 A* M* k- M: K3 S2 k
// 通过 WIN32_bios 获取 BIOS 信息:
( ]7 B3 c5 V, Z! pvoid __fastcall TForm1::Button1Click(TObject *Sender)2 H5 B  @) k2 v# F& m7 I' \( G. B8 J
{
  N1 ?+ U# Z& d    Memo1->Lines->Add("================== [WIN32_bios] =================");
5 F. `9 @. @6 Q9 ]    GetWmiInfo(Memo1->Lines, "WIN32_bios");
6 [: N: b" u7 x/ |* t) j9 ~: J6 M    Memo1->Lines->Add("");9 @! ]) s; C% z
}1 E+ ~" {! o: [4 Z5 K

4 _* X5 f2 b" s' ~4 c$ x--------------------------------------------------------------------------------
8 v" K$ m. m! F! a9 L9 s
% v9 X2 F- }6 X, NWMI 可以访问的信息类型有:) \2 }5 z% X* m  a
  Win32_1394Controller* D3 H% J7 K5 B* C6 a' p5 S' \
  Win32_BaseBoard
& w( T: B8 l% t   Win32_Battery" O" K( v2 f9 U9 i
  Win32_BIOS
+ \2 t( W9 n' W9 ]; c   Win32_Bus
5 A) [  q0 [; j1 @7 ]   Win32_CacheMemory
" u! X1 h5 s3 Y# e   Win32_CDROMDrive5 n8 |& O7 m, ]4 |: {
  Win32_CurrentProbe; S. g) v9 w  H2 N  y" c
  Win32_DesktopMonitor
) M3 k9 e, s3 n0 L   Win32_DeviceMemoryAddress2 v' P' l, J3 w
  Win32_DiskDrive
% G( ?. {! C+ o, E  F7 u   Win32_DisplayConfiguration1 K) d! D% }8 l2 o8 t
  Win32_DisplayControllerConfiguration
+ F7 x! ~  F9 s5 w   Win32_DMAChannel
  a# c0 d& h# S6 t   Win32_Fan/ L$ R! m7 f, A9 A/ r
  Win32_FloppyController# T8 _, W4 I' {0 t4 q4 O% F
  Win32_FloppyDrive; p. Y' s( }3 u
  Win32_HeatPipe  I6 \7 P6 c9 g5 g! r
  Win32_IDEController
  [4 S) c8 n2 c   Win32_InfraredDevice/ F7 N- `( Z) J4 }6 b
  Win32_IRQResource
3 v/ W$ o0 i% o  z# [, c   Win32_Keyboard
* V) Q4 Z: b, t1 A   Win32_MemoryArray: I1 h& M  q0 N
  Win32_MemoryDevice) }4 s7 @3 d) t
  Win32_MotherboardDevice2 u+ ^9 B7 [; ]
  Win32_NetworkAdapter
  y* `1 X; g2 {. P) h) B$ {   Win32_NetworkAdapterConfiguration2 }9 ~) r$ C  ?$ [. |
  Win32_OnBoardDevice) b- J7 S9 A+ C3 U" L7 U
  Win32_ParallelPort5 G9 O3 x  [9 |* J0 r  W
  Win32_PCMCIAController
5 |: B- g  a' u& X2 G   Win32_PhysicalMemory
; n& c! ~3 R: q% R$ b) k6 z   Win32_PhysicalMemoryArray
& H# P% J- c; o7 O0 D. X   Win32_PnPEntity- }, q5 O4 }/ n$ N! X" L( D
  Win32_PointingDevice
: t4 m* k. Y$ j& T3 L   Win32_PortableBattery4 X! I! M: [* U& a% G
  Win32_PortConnector
1 u  t! k! P6 x/ R9 m( Z   Win32_PortResource
, P! X0 }6 n; `# _1 W4 E: e! o   Win32_POTSModem
) j" o1 s" ~$ {8 A% b4 z   Win32_PowerManagementEvent
$ }0 O3 N) g0 j   Win32_Printer
& b' T. l& j6 k   Win32_PrinterConfiguration* ?; O% J  k2 e8 b; Z
  Win32_PrintJob. j# Q, g( V# ]2 n3 y5 O2 f/ c: T
  Win32_Processor
2 v4 a: G' ]6 K; @/ i5 H   Win32_Refrigeration0 b0 P: s8 K* Q/ P. @. g1 q" |) V- d
  Win32_SerialPort
& S0 q; `" T: u! z: b/ g   Win32_SerialPortConfiguration
3 h& R% I$ Z: g% B& P% O0 h   Win32_SMBIOSMemory
, f0 h+ A9 `# L7 T; O# [# f   Win32_SoundDevice
& s4 d" O+ U0 L7 w   Win32_SystemEnclosure& T  ]  @/ H* A0 q0 g' G
  Win32_SystemMemoryResource$ n2 r  D1 h. s6 p/ e* P0 h
  Win32_SystemSlot
1 ]5 x" u) o% V% W) n$ F/ g   Win32_TapeDrive# Y! Q+ I7 g5 D
  Win32_TemperatureProbe
) G- f: N8 o/ T% t# Y0 w2 ^$ X   Win32_UninterruptiblePowerSupply( `8 H4 f, F4 b) J0 W
  Win32_USBController
) ~: D' O* c& d% J3 c# C7 @# V   Win32_VideoConfiguration* W- w9 p" P8 J* ^
  Win32_VideoController5 x$ F: X9 f7 T0 V
  Win32_VoltageProbe
' w3 H. ^3 r! o( `4 D/ ?# C" c, F4 }1 e
以上类型(字符串值)通过前面写的函数 GetWmiInfo 可以得到相应的信息, 例如 GetWmiInfo(Memo1->Lines, "WIN32_bios");
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-1-29 23:42 , Processed in 0.022039 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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