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

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

[复制链接]
发表于 2005-5-22 17:04:00 | 显示全部楼层 |阅读模式
  Victor Chen, (C++ 爱好者)
( j9 A& f5 O/ O% O* u
7 _1 H$ Z! r& w/ X9 I3 i2 `5 `  j: k8 H
--------------------------------------------------------------------------------  `. o) Z+ C9 f2 M
WMI: Windows Management Instrumentation (Windows 管理工具)- M2 h- @* f& o2 C
  通过 WMI 可以获取主板、BIOS、磁盘、显卡、网络等几乎所有的系统信息。 8 U$ F2 a& b0 O5 }3 a% X& g
  利用这个工具可以管理本地或客户端系统中几乎所有的信息。
! q$ J! {, F# e. r/ H/ G   很多网络管理工具都是基于WMI开发的。在 Windows NT/2000/XP/2003 都有这个工具, 在 Windows 98 里面可以选择安装这个工具。
7 |8 |* ^4 w3 }% P+ w+ c; ^- i  e' F5 O7 W' `
--------------------------------------------------------------------------------
5 u; G3 e) s+ G$ J; ~) j9 UBCB 的 WMI 库文件 wbemuuid.lib 由本站提供, 包含在本页下面的程序源码下载里面  b) ]7 C& F3 }; g4 N

& g1 x# v+ l" ]) x--------------------------------------------------------------------------------
3 T5 p2 @0 a& z  u8 h" ~. j/ y( p, f0 i① 初始化 COM 接口:; ]/ Q' ~% J1 O
  访问 WMI, 必须先初始化 COM 接口, 在程序的一开始调用 CoInitialize(NULL); 初始化, 在结束时调用 CoUninitialize(); 释放资源。
, S4 W' R1 A( u) A; t   这两个函数在 #include <comdef.h> 里面定义。
9 y4 ~( Z" f. M* B( j' h* w. C; e5 D' q0 N# R) H2 D" W) j$ Z' K4 \1 X9 a
② 获取访问 WMI 权限:
$ N2 G- O  N4 q) u$ z8 O  Q/ t, v: R. h   CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);
4 \7 W8 R; N3 M# k: V4 H   如果这个函数返回 S_OK 获取权限成功, 否则为失败。
. l' J; [6 ^6 T! t9 n: r, c* E8 v6 l& b. {; v
③ 通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息:* Q8 \' u3 Z; {% B' a$ m
  这个函数的参数: lpList 返回信息, wsClass 为要查找的系统信息类, 这些 COM 接口在 #include <wbemidl.h> 里定义。
. B! k& t6 P" |% ?+ [$ T
/ q/ P( c. [% @8 }7 Q" wvoid GetWmiInfo(TStrings *lpList, WideString wsClass)( ~" Z& ?" c" U3 S
{
: ]6 B4 ^9 ^8 a6 y! _8 J" j  IWbemLocator *pWbemLocator = NULL;
' ~; e4 V3 S- S) Z* G  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)1 e# T: D0 O. s+ Q$ q' P% {
  {: L  q* z% T3 q" C
    IWbemServices *pWbemServices = NULL;
  X  P. K7 B2 O! z1 L. i. U) b     WideString wsNamespace = (L"root\\cimv2");
4 Z' J1 ]" f9 ^6 `     if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)7 S- I1 S% f3 E5 p
     {- E8 f1 k4 p! y$ `9 v
       IEnumWbemClassObject *pEnumClassObject = NULL;
: Z; t- }% _: `7 {# p) |+ W9 Y        WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;5 y. Y2 V9 W* t1 W! r% K
       if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)
# s# {: _8 }0 B2 Z' c% Y+ B; r* N         {2 A- F4 G9 a9 Z0 |0 m! p8 w
          IWbemClassObject *pClassObject = NULL;! C5 m- L9 N* L) G5 `- Q) c- [
          ULONG uCount = 1, uReturned;
' W* M7 q# O. V           if(pEnumClassObject->Reset() == S_OK)2 f" _9 J. Z3 B6 E+ V
           {" Y8 d6 T; p- {9 R& P
             int iEnumIdx = 0;+ Q$ A7 J- D- B0 {
             while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
5 @- H" _9 L' m" Q' p: U  w8 [               {
, b: g( Q& Z! M5 c0 N# l                 lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");
* ^* n3 B7 F/ O' ~% q# p
6 f7 }) T5 Q( {2 Z                 SAFEARRAY *pvNames = NULL;# t% S& ~+ R7 p6 E: q$ v! o
                if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)' P8 @+ R/ W" L' K3 w6 @0 G
                 {
4 {! x. g& ]. i8 n% }( `1 N2 ~) f0 R* Z                    long vbl, vbu;' r9 T4 C! {+ _) @& f; Q
                   SafeArrayGetLBound(pvNames, 1, &vbl);
  {' w2 V& B0 c2 Y$ k                    SafeArrayGetUBound(pvNames, 1, &vbu);3 h8 e$ @5 \+ c. K/ ^
                   for(long idx=vbl; idx<=vbu; idx++)
6 d6 S( B! }0 S7 c                     {
: m2 t( [9 S$ G$ P                       long aidx = idx;8 A. I, s  N- {0 J& |# E8 p9 V
                      wchar_t *wsName = 0;- u, m0 X' s" m
                      VARIANT vValue;, n  A8 b) D6 V' K+ d
                      VariantInit(&vValue);
% B! w3 A( l- j5 [- g9 E. c                       SafeArrayGetElement(pvNames, &aidx, &wsName);
' M4 L. j! x9 b+ B% h, `8 g$ q: \  \2 G3 b1 N* E1 |+ e% }
                      BSTR bs = SysAllocString(wsName);) m; E6 D- m/ |: c1 X
                      HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);
$ }* {+ f# G0 l# M! Q+ P- {# v* b4 Z                       SysFreeString(bs);
% O4 b/ y( @, S; e1 f. A1 d
+ E2 I* O$ Q8 y8 D4 g) \0 `' ]                       if(hRes == S_OK)
# J0 T, {- X1 A                        {
2 {, _6 j% ?! F& P2 @                          AnsiString s;+ A, j0 y/ Y* D0 ?
                         Variant v = *(Variant*)&vValue;
6 J8 X, \: Y% _* ]9 J! {- E( u: ]                          if(v.IsArray())
2 ~6 Q7 ^5 K0 d& ]+ b! S                           {
( D. ^# L/ t) N! `5 s/ T/ z                             for(int i=v.ArrayLowBound(); i<=v.ArrayHighBound(); i++)1 f" b, Q' ?9 I! n  t4 x) d8 k
                             {
# L& V4 n5 e$ C5 A' u( R                                Variant a = v.GetElement(i);
, b7 M& M/ d. F& ?' h                                if(!s.IsEmpty())8 M4 P9 J3 ^& |7 N- X. Z. W
                                 s+=", ";3 [+ z3 g0 |! c; `
                               s+=VarToStr(a);/ g9 {% z6 F  `1 d9 O8 Y  x
                             }$ B; x2 D' |4 f' J" V9 ]; f1 L
                          }
) d4 t: o0 K1 k5 R                          else
! M; p% k9 M* S$ i* X+ P9 C                           {
  M" \, l0 O9 J8 J                             s = VarToStr(v);. l4 _: I* f6 b! Y& |" v
                          }
. g; M* V$ Z" b9 _, E) N0 c                          lpList->Add(AnsiString(wsName)+"="+s);
& ~0 A* S" }% S0 C                        }
4 ^8 x1 z" L7 ]) A0 m
0 h  ^( y8 @) Z: Z+ Y; P                       VariantClear(&vValue);: }* R$ V* u+ H3 K9 L5 s
                      SysFreeString(wsName);
* {+ P+ t3 q2 U8 n3 Z                     }
! I1 V$ H7 f! \7 J1 u$ e5 v                  }  s; X* M/ S  Y" O# P
                if(pvNames)SafeArrayDestroy(pvNames);  S, d+ |, b5 I3 i& k
                iEnumIdx++;
' ^& p: p: t& ^. H& P9 E               }9 T+ F$ r! M1 S7 E& p: J* }: T
           }9 y- c% K0 p, j0 i9 m" ]/ U
          if(pClassObject)pClassObject->Release();
) }2 A( F$ D  {  ?+ b         }
: Z4 I1 e5 E# B; u' t6 ]! f; i        if(pEnumClassObject)pEnumClassObject->Release();7 W& y4 A, a  S' b+ |2 S& T; o4 [$ I
     }( y' h# K( w- L+ r
    if(pWbemServices)pWbemServices->Release();
* Z9 X2 H# _# @1 n4 |   }! d1 m  b2 y1 ]/ V* V5 x  ?0 b
  if(pWbemLocator)pWbemLocator->Release();- w6 i' y( Q3 S( |  e
}/ f( x, k2 x1 v8 G" U  ]
//---------------------------------------------------------------------------
, n5 e: ]) p# B; D. C0 @- f6 \- W5 M, ~) y! f! |
// 通过 WIN32_bios 获取 BIOS 信息:
/ ?* p- `0 r+ ^) ~void __fastcall TForm1::Button1Click(TObject *Sender)
$ h% r/ k9 T# t8 |7 x" v: v{
* T6 W, [1 ^) L, l  M( X* @6 }    Memo1->Lines->Add("================== [WIN32_bios] =================");9 G' O- w9 @1 S. o) j5 B' J; L
   GetWmiInfo(Memo1->Lines, "WIN32_bios");
. u+ M: f8 f7 g. f* }    Memo1->Lines->Add("");, ]: K  i% p4 x; W
}# c. ~1 A$ ~  n4 C  c2 p- q: z
! h( G! o& |4 e
--------------------------------------------------------------------------------
: V1 O, J+ H# c* @: x- o. `6 Q5 D3 |- R& H8 o; }( r2 N0 b3 ]
WMI 可以访问的信息类型有:
+ c9 ^' O! }; @- B; _   Win32_1394Controller
! b8 F9 |* J1 ?' M+ M6 J# S, p   Win32_BaseBoard7 J4 B$ f( `, S" U& X
  Win32_Battery
7 y* A3 y$ O( x- v! y: x9 V   Win32_BIOS1 K' S& ^  S+ |8 W" O  U( L
  Win32_Bus: a* ^8 |, d! Z* G8 h/ F
  Win32_CacheMemory0 s2 k( P  Q" K. g6 P8 M% I
  Win32_CDROMDrive
2 q5 O' v: M7 f& ?6 Q  u$ G* L8 a   Win32_CurrentProbe: I# z! D' a1 F
  Win32_DesktopMonitor' ?! ?  j) |9 u  |, B/ A
  Win32_DeviceMemoryAddress
5 d$ {5 e: j, \0 s+ m6 k   Win32_DiskDrive- W5 e& a( ?' j* j& A5 ~: l
  Win32_DisplayConfiguration3 @# N! _# C. w$ Q# _' [
  Win32_DisplayControllerConfiguration
1 R5 }7 S) a# E/ J9 z   Win32_DMAChannel
" d3 C! g, S5 O) H2 W* W8 G   Win32_Fan: \& A+ v: F, D- s6 o% U# A
  Win32_FloppyController, T# D( E" k  `3 C6 w  b# D1 R
  Win32_FloppyDrive
6 _0 X3 A7 O! z8 F( U   Win32_HeatPipe. A. |8 V/ S+ }( E9 w, f2 p
  Win32_IDEController
4 D6 G: l% J9 r1 f- i* P   Win32_InfraredDevice* K! i9 e1 a" ^" _' b
  Win32_IRQResource
8 A- F( g  ~; L+ F   Win32_Keyboard2 c$ W: Q5 g: B; t3 v
  Win32_MemoryArray9 G- I3 W* m' O# O( I0 `
  Win32_MemoryDevice0 o) o. E$ e, ~7 Q
  Win32_MotherboardDevice
7 g( R8 G( ~+ P3 \# n: L1 M) x, N/ F   Win32_NetworkAdapter
8 Q. Q+ W* q* M6 M9 b7 L# i4 c2 m! w   Win32_NetworkAdapterConfiguration
& u/ f' V* d) ~; W   Win32_OnBoardDevice
3 H3 g, S1 b$ r8 D- j/ _9 z3 t   Win32_ParallelPort1 z+ Z6 j* k* ^* l! B+ v! B
  Win32_PCMCIAController0 G, a2 M! Q1 q- ?" B* F' E+ g
  Win32_PhysicalMemory$ \3 ~: b5 {" w
  Win32_PhysicalMemoryArray
* a3 w! n+ B- u. i8 Y2 U2 F   Win32_PnPEntity$ \* b  i# ?  W  Z2 X( D+ F
  Win32_PointingDevice0 h+ J' {& n% g# w( S, u  ^# I
  Win32_PortableBattery
# p) L; e4 l! O5 G   Win32_PortConnector
' P' i( x+ I2 `2 H' j% l   Win32_PortResource  X& r4 A/ s" T: E
  Win32_POTSModem/ Q, q  O# C: k" u" u
  Win32_PowerManagementEvent
) P' a# z8 {' O5 m1 ^+ d! B   Win32_Printer
+ r& Q  Y8 A! Y+ N% @   Win32_PrinterConfiguration
5 e' Y5 I7 h( l0 _   Win32_PrintJob
4 q8 d2 O- }& G. X- ]5 g1 I- T9 S   Win32_Processor
1 ?* D7 F3 K! d" c1 r( E  y   Win32_Refrigeration
, G6 _) R$ c+ m  q   Win32_SerialPort2 u; O: x3 c+ \- ^
  Win32_SerialPortConfiguration( Z: s2 o5 A* {7 |
  Win32_SMBIOSMemory' P  `( ~& U9 F& o" L+ H; c
  Win32_SoundDevice
7 \3 |; [- ]" F6 [4 h7 ]# _7 U   Win32_SystemEnclosure
' q& J& y: z' }* u/ K8 U, J0 \   Win32_SystemMemoryResource* |3 s+ U4 Z" Q
  Win32_SystemSlot
- X7 N1 z5 n/ I" a2 q1 r   Win32_TapeDrive
( @/ s9 V* e& ?/ i& t" _   Win32_TemperatureProbe$ W. ?7 i1 T% f- f& W9 M  Z
  Win32_UninterruptiblePowerSupply
" S$ l: g* r! O& r: m   Win32_USBController2 V+ X/ @1 n6 _; [
  Win32_VideoConfiguration
& ?1 y+ B: b5 A: m0 [$ k   Win32_VideoController
) c& n- V: O6 l" R1 ~. Y: W   Win32_VoltageProbe
9 t# D  g1 J2 E. G/ D! _# b8 N; B& n$ V+ t
以上类型(字符串值)通过前面写的函数 GetWmiInfo 可以得到相应的信息, 例如 GetWmiInfo(Memo1->Lines, "WIN32_bios");
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-2-2 23:42 , Processed in 0.019973 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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