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

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

[复制链接]
发表于 2005-5-22 17:04:00 | 显示全部楼层 |阅读模式
  Victor Chen, (C++ 爱好者)
* g$ q) x& [$ u9 |8 m4 G. b3 B, z& w& i8 f
) ^* E1 A5 k  e, ~
--------------------------------------------------------------------------------& c& w; {: C$ [; L4 a' d
WMI: Windows Management Instrumentation (Windows 管理工具)
2 b, L4 c# X! }1 H# _   通过 WMI 可以获取主板、BIOS、磁盘、显卡、网络等几乎所有的系统信息。 # c2 h9 f* w4 T3 M) J1 N" [
  利用这个工具可以管理本地或客户端系统中几乎所有的信息。
  k( s, Y3 O% i3 i; V3 F5 K   很多网络管理工具都是基于WMI开发的。在 Windows NT/2000/XP/2003 都有这个工具, 在 Windows 98 里面可以选择安装这个工具。 + b  x$ }" M  }0 l5 z
, u. A! Q5 s- P7 A6 i- v) F
--------------------------------------------------------------------------------' P6 J+ E& x0 m
BCB 的 WMI 库文件 wbemuuid.lib 由本站提供, 包含在本页下面的程序源码下载里面; p9 B. n) e9 H, ~" ~3 i* N1 x; d& D
8 J) \# ]" K4 c5 S+ J6 f  ^0 Z& W/ X
--------------------------------------------------------------------------------
  x7 W: y9 c( N( |* y* L/ l3 v+ [① 初始化 COM 接口:
% W3 V, W, s3 N( e. x% l   访问 WMI, 必须先初始化 COM 接口, 在程序的一开始调用 CoInitialize(NULL); 初始化, 在结束时调用 CoUninitialize(); 释放资源。
8 }6 X3 v  E% e1 p5 q: e  m& [' ]   这两个函数在 #include <comdef.h> 里面定义。$ R, K! n3 I3 e  d, D+ b& R& N$ N

* ^6 ?! O; D& v1 z, B$ M+ O3 W! e" D② 获取访问 WMI 权限:
. m! y: _/ X8 A; a4 M( |; z   CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);
1 `$ z8 O- h' Q6 X$ o   如果这个函数返回 S_OK 获取权限成功, 否则为失败。
) m6 z; P* `9 ~5 ~# E4 U4 v' {9 h" e# k% {! A+ ^# i' G
③ 通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息:, D( \$ h' J+ p; _- e5 c
  这个函数的参数: lpList 返回信息, wsClass 为要查找的系统信息类, 这些 COM 接口在 #include <wbemidl.h> 里定义。4 N+ Z, g$ F1 Q2 v
6 {$ s& E1 C$ n
void GetWmiInfo(TStrings *lpList, WideString wsClass)
' D5 @5 |1 O$ K2 i3 d{
. |/ T3 W: B) w, A  IWbemLocator *pWbemLocator = NULL;3 T. K* p4 e. r+ Z! w
  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)9 _/ L$ z4 C# ^, Q
  {
  I4 l! T1 |! o     IWbemServices *pWbemServices = NULL;
/ W# |" q. M8 P1 s$ H5 f8 t/ c" P$ R5 e3 p     WideString wsNamespace = (L"root\\cimv2");8 s) I- N& L; i6 l; _- D
    if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)2 S' V$ {  i5 D& \. D
     {4 c! m( T" l- X! ?; B: M
       IEnumWbemClassObject *pEnumClassObject = NULL;! [1 f0 r! y8 U. ^8 s
       WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;
" a1 {: C* ]. x& H, g+ [! a        if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK): {% n$ U1 ~6 @5 {& b" ~- D3 m
        {
3 T# Q% R' f8 A3 D5 W9 M# H1 k/ P           IWbemClassObject *pClassObject = NULL;! T+ O4 u1 l! `# u5 a
          ULONG uCount = 1, uReturned;8 c( d7 Y8 T6 G' V/ x, J
          if(pEnumClassObject->Reset() == S_OK)
' R/ E* p. K! R8 L" Z* q            {$ o! s' g& ^2 M- A
             int iEnumIdx = 0;. G6 @2 ]+ [, J8 G' f
             while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)$ p: n+ l" p5 q* j" s3 ]7 A, V: z
              {8 P% S" w6 [9 ]1 a
                lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");
' n% j/ X! C" I" l9 ~$ m9 ^
: h. \  p- G1 ?) ^9 P3 a7 n                 SAFEARRAY *pvNames = NULL;
, D- [  V" H6 ^4 V1 H7 D) |+ v% F0 T                 if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)$ f5 z! F2 Q% m! Q1 y1 f' j5 Z
                 {' r0 D# g: T: A4 p  t' f+ X% y
                   long vbl, vbu;8 |  k+ u4 N1 J$ ?2 ?7 Q- B8 O+ _
                   SafeArrayGetLBound(pvNames, 1, &vbl);
9 d0 I0 A9 g" j8 i7 \& ^                    SafeArrayGetUBound(pvNames, 1, &vbu);
5 }9 L6 H7 m% f" l. G2 h# o  S                    for(long idx=vbl; idx<=vbu; idx++); h; E1 V% _& k9 l! q% M9 _
                    {
7 z$ V% c4 O( E$ H+ ?' S; D                       long aidx = idx;3 H" f/ q" \) I2 a4 [2 r. }. F
                      wchar_t *wsName = 0;  g, K) k/ S& [" Z
                      VARIANT vValue;+ ~# ^  X9 \: t' J
                      VariantInit(&vValue);3 v5 c4 X5 Z  N. K; N
                      SafeArrayGetElement(pvNames, &aidx, &wsName);
0 L9 O8 F( ~, v6 h/ f2 b8 z8 m
- A' N4 A, m' T8 W! _& e" H                       BSTR bs = SysAllocString(wsName);2 q2 b' M3 P7 W7 a+ P
                      HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);3 o( p! y% y9 j$ R8 E0 M- w
                      SysFreeString(bs);
+ c$ W& z, [1 Y' o$ W+ A( g$ w$ r8 u/ n: r. V+ C, c
                      if(hRes == S_OK)
, |. M% c3 r2 D& H& o# u                        {. {2 F8 V) J+ @9 N- R
                         AnsiString s;; l4 R/ |8 _9 J$ s. e  C2 s0 c1 U
                         Variant v = *(Variant*)&vValue;
6 I' K0 u8 j# J+ Q! B( V                          if(v.IsArray())
6 ]& b- z. W, N0 q+ s# z( v3 `                           {
' _5 p( d7 }' v0 F                             for(int i=v.ArrayLowBound(); i<=v.ArrayHighBound(); i++)
$ v! ?! ?$ o. [1 c4 C                              {
8 \! |# U* e% k4 I* m                                Variant a = v.GetElement(i);  v9 u$ K0 _9 u1 y3 ]3 ]
                               if(!s.IsEmpty()): ~, e2 |: i6 t* h
                                 s+=", ";
' W+ O& q5 u1 j. E& B0 K. L5 W                                s+=VarToStr(a);  z8 z/ E0 X4 l& c% q. C
                             }# q+ U! {' L- Y+ W3 {! r1 t! y+ N7 t
                          }
! O0 t6 [% R7 i4 q# a  {                          else, A3 h) U5 q( X6 V) t9 z
                          {
( w2 Y5 R7 |' B6 R5 K. q                             s = VarToStr(v);
& \8 v0 U% p" L                           }
7 C, ]; f+ u0 m                          lpList->Add(AnsiString(wsName)+"="+s);3 w  y( T; A: d
                       }; Z5 a! T9 A1 C, Q

, c$ h% x! m) t  Y                       VariantClear(&vValue);8 E, c4 ?9 b  }  R6 I7 y  f
                      SysFreeString(wsName);0 i9 Y0 e! N) V4 W9 @5 v( O9 `  [$ E
                    }
+ r+ f* D4 f$ v) d. B0 M; U                  }# O: ?( u* p! v5 }& W
                if(pvNames)SafeArrayDestroy(pvNames);
# z1 J6 A  m0 B$ \3 ]$ n                 iEnumIdx++;" Q+ `+ V) M6 \8 f* h( b3 G
              }
; m! C; g. L( Z. O( {; E9 j            }) w' C; o3 Z1 F  F$ w" \
          if(pClassObject)pClassObject->Release();4 c) W" C+ ?: K/ c
        }
, a4 N$ y! M8 p, h        if(pEnumClassObject)pEnumClassObject->Release();# `% t: X0 F* o3 b+ C7 v
     }- N* t+ r% R% H% M$ W+ e8 [: |* u
    if(pWbemServices)pWbemServices->Release();
# J$ I4 U" J, B0 [" V& i6 e   }+ R1 D* N7 M% S$ L& J. b9 x8 ^' P
  if(pWbemLocator)pWbemLocator->Release();5 P2 y% {5 N" |
}
; ^" ~% ?6 s+ [+ o//---------------------------------------------------------------------------
7 T" Y' L: {' _' z, \8 o! d$ O# u! l
8 `  @" g3 O# ?0 b( b" V: ^// 通过 WIN32_bios 获取 BIOS 信息:0 v3 f! K( \0 M$ M( Y7 \+ L
void __fastcall TForm1::Button1Click(TObject *Sender)9 M' Z7 `! i. ?+ C& ]  `
{; q+ R/ Q  f- N2 C  ?
   Memo1->Lines->Add("================== [WIN32_bios] =================");
, `9 x- W6 r8 e  F) F    GetWmiInfo(Memo1->Lines, "WIN32_bios");
- L5 p1 X2 R0 ]5 q    Memo1->Lines->Add("");
, s* _0 A8 g; O9 l: t4 }: A}3 n' @0 `8 S) {

, \- t& I  E9 f( i$ y+ y4 ?& u--------------------------------------------------------------------------------* c, V6 o* q" y
; n: j& r6 D8 t$ q- @# X
WMI 可以访问的信息类型有:8 H3 \, J" t. s$ x. q- p+ T+ H9 [' p9 i  H. j
  Win32_1394Controller9 \2 z9 v! {6 q+ l
  Win32_BaseBoard2 g' f! t' x% s' s& S& o1 @
  Win32_Battery
9 j  E1 d5 H- ]8 ~( a   Win32_BIOS6 v! ^) C# \3 C5 U0 k
  Win32_Bus
' S5 s% R. w2 z5 }0 \9 i  U+ P4 q   Win32_CacheMemory  K0 ?3 s) B5 Q  Z" |- ]  e
  Win32_CDROMDrive% f/ U* L  t1 Y! s
  Win32_CurrentProbe! _" E+ g) W+ L+ f
  Win32_DesktopMonitor# s5 w6 ~6 _  ~
  Win32_DeviceMemoryAddress
% ~4 x. I6 K5 \" s* d( T" e   Win32_DiskDrive
, P2 `& C0 H! ^  Q5 r' R: b   Win32_DisplayConfiguration
# X  x: I' Y) U( S   Win32_DisplayControllerConfiguration
$ _4 ~" t- C' n9 l7 L1 N  o   Win32_DMAChannel
1 A8 H$ d; ?" D4 ?   Win32_Fan  `" G/ l, f& s6 Q
  Win32_FloppyController
1 u' Y2 `/ ?7 L   Win32_FloppyDrive
, Y' r2 o3 h0 Y' K! y   Win32_HeatPipe
! N+ s. a4 m7 }+ g5 {2 J   Win32_IDEController
9 o, O7 Z$ t2 O7 o* v2 l   Win32_InfraredDevice
6 j+ g1 r- r. c6 f   Win32_IRQResource
# \. e7 v4 k7 a' f& }   Win32_Keyboard6 ^; o1 Q% x% F5 @
  Win32_MemoryArray" ?2 M# P( ^. `% n1 r+ S5 ^6 t
  Win32_MemoryDevice
  a6 s% J$ Q/ ?   Win32_MotherboardDevice3 I9 d- q2 Z& H6 Y
  Win32_NetworkAdapter0 Z5 c0 k- t. O- K  t. |0 ?
  Win32_NetworkAdapterConfiguration, `: t% {7 A. z5 z8 I7 k
  Win32_OnBoardDevice* R+ ]; z/ S3 y0 K$ [% j+ Q
  Win32_ParallelPort
+ [: g/ N+ R# ?; m5 C9 q& M   Win32_PCMCIAController
4 z1 ]% p9 P& L5 s3 c5 p   Win32_PhysicalMemory
8 J' S" Z; }, x   Win32_PhysicalMemoryArray5 w1 y9 Q* a; O: J, B: ~
  Win32_PnPEntity) c: N1 i& b# w5 a
  Win32_PointingDevice% ?8 y. i, b% o7 R
  Win32_PortableBattery; U2 S( a/ [! k, l
  Win32_PortConnector
) p& V! o# D5 d8 K* V, `* R   Win32_PortResource* K& B! @- b, Y) a
  Win32_POTSModem
+ {+ L4 R$ B, m  N& _, i5 P& n   Win32_PowerManagementEvent2 Q  m3 |8 J+ h7 f: `
  Win32_Printer
1 }, P) t+ w+ a1 \! e% ^/ H   Win32_PrinterConfiguration: Q( a+ M# n1 }- s0 O. R
  Win32_PrintJob
! D( E. n1 b6 P9 W# [5 m8 q   Win32_Processor
/ d- u/ |2 p; E, j7 T( {   Win32_Refrigeration
' H2 ?5 T' E) D5 U  G   Win32_SerialPort
6 i7 I2 H; J3 |8 U7 j( L   Win32_SerialPortConfiguration9 Y- O, p0 H. j1 u
  Win32_SMBIOSMemory
7 `# U' {, U9 r) d3 b   Win32_SoundDevice
( M* E/ V* n- ?% T0 b5 ^   Win32_SystemEnclosure
% B2 k' j7 f& _( [7 S  v   Win32_SystemMemoryResource' J* Y4 ~; D) M- [+ z( F5 X
  Win32_SystemSlot
2 ~+ I. n4 }/ ?8 y, _. V; f   Win32_TapeDrive% [  ~* M8 H" M
  Win32_TemperatureProbe; l! I% V8 \/ L
  Win32_UninterruptiblePowerSupply5 O& c( y% D7 u# O- [# k& n
  Win32_USBController
& o- A7 E) s2 }! M! K1 E7 C, \0 X8 e* q   Win32_VideoConfiguration
! t2 ]1 Q# m0 n1 `- q" b   Win32_VideoController
; ~2 h- C, G* Y  _" S2 x   Win32_VoltageProbe
3 W0 J7 J. _. g: V$ Q" c% }& ~6 R. z3 \5 T2 Z( d
以上类型(字符串值)通过前面写的函数 GetWmiInfo 可以得到相应的信息, 例如 GetWmiInfo(Memo1->Lines, "WIN32_bios");
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-1-22 08:26 , Processed in 0.019363 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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