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

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

[复制链接]
发表于 2005-5-22 17:04:00 | 显示全部楼层 |阅读模式
  Victor Chen, (C++ 爱好者)
% F# g0 n5 p  j2 w
2 N, R1 Y5 H/ u9 |! K- s* e3 u3 n( w
--------------------------------------------------------------------------------
9 d8 I1 C! ^) T3 `* oWMI: Windows Management Instrumentation (Windows 管理工具)
; ?% }8 l0 }6 M$ C! s+ }1 C1 m   通过 WMI 可以获取主板、BIOS、磁盘、显卡、网络等几乎所有的系统信息。 ; L' g% s) u. J: h1 ^+ ~. p+ N4 _, N
  利用这个工具可以管理本地或客户端系统中几乎所有的信息。! S* ~/ l' y7 K8 T  ]
  很多网络管理工具都是基于WMI开发的。在 Windows NT/2000/XP/2003 都有这个工具, 在 Windows 98 里面可以选择安装这个工具。
  \8 H' y; E4 x: c& H  n. U2 g% `' h8 `: [7 Y/ z6 m
--------------------------------------------------------------------------------
& K0 t3 W2 R  E1 C) d( x9 ^8 rBCB 的 WMI 库文件 wbemuuid.lib 由本站提供, 包含在本页下面的程序源码下载里面
0 b9 A: l- N9 Y9 W" t4 A' m
. a- W! V, g7 Q3 l% r) I--------------------------------------------------------------------------------
# ~0 F3 B0 G9 ]- z+ {/ B1 M. c① 初始化 COM 接口:
" ~& D6 Z* {  S* L' ?6 {' t   访问 WMI, 必须先初始化 COM 接口, 在程序的一开始调用 CoInitialize(NULL); 初始化, 在结束时调用 CoUninitialize(); 释放资源。2 x3 ^+ m' ~' o% s# K
  这两个函数在 #include <comdef.h> 里面定义。6 a# E+ K9 h0 }! z( w$ W/ U1 o
% S8 D3 X! r* V6 e1 D9 J' {; q
② 获取访问 WMI 权限:, h: n" E7 g  U2 |) F5 n2 M. ]
  CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);
: @( k* W$ \$ z6 V; r   如果这个函数返回 S_OK 获取权限成功, 否则为失败。3 \& H# G0 t8 o! h( F  N9 p

! Y* U9 u6 ]$ X: H  n7 K' E③ 通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息:. N5 z2 O7 I- v/ w0 I
  这个函数的参数: lpList 返回信息, wsClass 为要查找的系统信息类, 这些 COM 接口在 #include <wbemidl.h> 里定义。
, v% u5 l. g" T( D% o# [& {' ]7 a% C
void GetWmiInfo(TStrings *lpList, WideString wsClass)
8 N) U& X" E! ?* E{
2 p& t: t/ F5 t, I2 z) c6 o( }9 t' }  IWbemLocator *pWbemLocator = NULL;" M  r' Z- h( @# E. P# W3 q) S4 k
  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)) C" H! N8 V: G5 ]% _
  {" o0 W# |, X7 d* R8 H
    IWbemServices *pWbemServices = NULL;* x3 `& Z# r+ |: ]
    WideString wsNamespace = (L"root\\cimv2");/ ^; Q3 z; n  W3 O
    if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)) \1 X* \& J( e4 i: P
     {) U8 O8 F8 `# s3 L
       IEnumWbemClassObject *pEnumClassObject = NULL;
& e& _, S; W; n5 g; f4 q3 ]0 V        WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;
4 I4 B5 R2 t: ]6 @, u; u$ w" k" R% \        if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)3 I, ]  |4 b+ m% _
        {' t! p* r) C. w7 p* N/ q5 P3 o2 o
          IWbemClassObject *pClassObject = NULL;! t. |* g8 @0 T* l  q3 w$ K! e
          ULONG uCount = 1, uReturned;( ?' G* r0 G  i; Q
          if(pEnumClassObject->Reset() == S_OK)
  z& q3 a( a) ~$ q            {! s4 i+ N# I2 s& g& g' }
             int iEnumIdx = 0;
# Y, A$ v6 f& w) x+ R              while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)! A1 f& F$ {/ q
              {1 e3 z3 h0 Z, y1 |5 D5 g
                lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");, _7 ^8 B5 A* l: B6 y4 Y2 [

0 ^0 a" Z, D/ J+ s4 F' g* c  Y                 SAFEARRAY *pvNames = NULL;
2 k3 |4 ~' l6 q" P. w) L                 if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK), \4 j4 F5 e  F& k( ]
                 {; f7 M. L  l" T' g) Q& `
                   long vbl, vbu;. J5 w" o) g; J
                   SafeArrayGetLBound(pvNames, 1, &vbl);
* Z. t& H! t, B. k                    SafeArrayGetUBound(pvNames, 1, &vbu);& p* \1 l2 c. |+ V) v& ^
                   for(long idx=vbl; idx<=vbu; idx++)
2 R3 d8 |2 v( W9 E/ ~                     {
( B  l! ]3 K# S) v* X; \* u4 z. a                       long aidx = idx;3 x" ?' D/ }( N6 H" r
                      wchar_t *wsName = 0;
- D( A6 z9 k7 X7 Z                       VARIANT vValue;- X! Y2 q) I/ W* g/ q( V& _# F+ d
                      VariantInit(&vValue);
( N9 ?5 G/ L7 f. @                       SafeArrayGetElement(pvNames, &aidx, &wsName);! w$ X3 z" I# X5 r0 {: o+ k' z
5 W; {: E: x( h# \
                      BSTR bs = SysAllocString(wsName);/ e) L0 E4 j+ a: x2 f
                      HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);3 _# a: u7 \: Z4 R" ~. U
                      SysFreeString(bs);
$ @" {+ S( O8 x! c9 y- O& e# |7 X  e/ S% ]& P; V) u% X. F6 F; F5 Y
                      if(hRes == S_OK)" W7 x+ {9 V, _
                       {3 g5 H$ ]; o* P3 l: k3 Q& [' n3 v
                         AnsiString s;# o$ v& P9 r9 _( ^4 U) F% \
                         Variant v = *(Variant*)&vValue;% T3 V* p" c- o0 E% n
                         if(v.IsArray())
$ |3 a, H" T  a5 E" ?; y* ^                           {; p3 [5 _" Y! J6 f
                            for(int i=v.ArrayLowBound(); i<=v.ArrayHighBound(); i++)3 n+ f3 [( @; ^2 g6 y. I
                             {4 N, m! r& R  k0 c  l
                               Variant a = v.GetElement(i);- E0 B' j) V; J$ p6 C2 _
                               if(!s.IsEmpty())
, t% y* I! ?' Y' M5 i4 i& E( j                                  s+=", ";
! j; J/ s  f6 ?/ _' S, k: M                                s+=VarToStr(a);2 Y$ [6 c- a3 j5 U8 Z& P. ?
                             }
5 Y4 f! c* r$ i$ r/ F                           }9 |# M9 z0 a) i. X* F5 k4 L
                         else
+ _. Y( F0 x7 g, j$ D; G* {# x                           {
+ i4 T. Z: K- e7 u/ f                             s = VarToStr(v);1 T- ]% d4 Q& ^4 [+ E/ L  U' K- J+ l
                          }. @2 ~* _) U  p+ s  F
                         lpList->Add(AnsiString(wsName)+"="+s);- N+ B3 ^/ @$ g1 s5 u
                       }2 q, S6 l! u. P7 z  F

9 t6 \# w7 V* v$ g$ r                       VariantClear(&vValue);. Y8 H+ o3 i1 }! q
                      SysFreeString(wsName);9 F; r2 x% n. d1 s9 I7 Z
                    }1 F6 `6 ]1 b; \; F" R; v
                 }
9 R2 F# a% E; _. _$ c8 k                 if(pvNames)SafeArrayDestroy(pvNames);
' o, K! }+ _. @; O$ [& g# g                 iEnumIdx++;! z/ s* d. X' h1 q! g, {
              }
9 T4 U. h7 q; Q& Z* I8 C1 f            }
7 r8 d) ^( E& _3 E  @4 m           if(pClassObject)pClassObject->Release();. t6 m, W8 ?7 [) g) m2 c
        }9 r6 x  _  R/ L+ ^  Q9 a0 i7 Q
       if(pEnumClassObject)pEnumClassObject->Release();
4 N# Y0 k% f7 k0 \: f% F. ]      }! p  p# p0 D* T* L' D# F. ~0 V  N
    if(pWbemServices)pWbemServices->Release();6 y1 v, {) b$ l/ o3 D& c% f6 N1 J
  }8 D# w) @1 m. {6 r) c  e$ z
  if(pWbemLocator)pWbemLocator->Release();
( t) {- I: j; e" h- g: @" U: ^}& ]" l, p, N# [7 i  e1 k% P
//---------------------------------------------------------------------------1 _3 x6 I- o& k: M0 X
: N( }& F: X- r
// 通过 WIN32_bios 获取 BIOS 信息:9 H% x3 r# V  w
void __fastcall TForm1::Button1Click(TObject *Sender)/ G- F8 ~2 ~: \4 S
{/ X8 o# F/ X# k2 k6 a8 D
   Memo1->Lines->Add("================== [WIN32_bios] =================");* e; J% Q* Z6 _4 ?; t- }
   GetWmiInfo(Memo1->Lines, "WIN32_bios");
. J3 w1 ?3 J! b3 X    Memo1->Lines->Add("");! H$ P6 m1 ?) m
}& `# ?6 c. ~4 ^! c8 T; t

9 w7 M. d5 q+ q8 }--------------------------------------------------------------------------------- |- P0 ]9 x' Y# s2 j

+ p. Q# a. W3 L0 X/ }9 e, [4 MWMI 可以访问的信息类型有:( D, P, c/ c( ~3 n! M
  Win32_1394Controller
# K# @" D( R9 x& D$ I( F* [1 q4 {   Win32_BaseBoard
* Z+ q* Q  S" u" G! Y/ K# N& L   Win32_Battery4 n3 k" n0 o* B
  Win32_BIOS  [1 L1 o! e# b+ y6 c
  Win32_Bus, r. [8 ?' Y/ b4 n: O" U
  Win32_CacheMemory/ ~. L* L$ e, I# l3 v% j
  Win32_CDROMDrive
1 p) b+ d% E4 J4 W& C   Win32_CurrentProbe7 ~+ M" c) i: y
  Win32_DesktopMonitor* P) ]( P! A$ {' K: U0 }; {' T
  Win32_DeviceMemoryAddress
/ i; R/ g3 c! J$ o   Win32_DiskDrive
& s! k/ w, |% j3 a6 w3 n8 B+ X   Win32_DisplayConfiguration
  Q) y- c. O! e9 N. q. P" z   Win32_DisplayControllerConfiguration
+ V0 x" Y; \% \8 y0 v8 O   Win32_DMAChannel2 k# \. i" K# F
  Win32_Fan1 }& N. Y7 `5 A" V) K9 t* a
  Win32_FloppyController
  h8 V/ y2 x6 D* T5 K- p, {+ h   Win32_FloppyDrive" e/ Z4 w7 [3 z5 D7 Y, o$ b0 ?
  Win32_HeatPipe
& {) F/ n% w( J   Win32_IDEController
- {4 m. G5 i2 [0 S4 j( G% ]) D   Win32_InfraredDevice( E0 _2 f: G  j9 G; u7 B
  Win32_IRQResource
; z+ `" y) b$ q+ n) j, [5 w   Win32_Keyboard* p$ Q* r& f" C! C; M3 i
  Win32_MemoryArray/ d" l. \5 k! L! O9 w* P( b
  Win32_MemoryDevice( T  }7 |# i7 x% |! R# w
  Win32_MotherboardDevice$ s. J# @, Z" g8 ^' p0 z
  Win32_NetworkAdapter& e: L5 L3 \3 V/ T# h; u
  Win32_NetworkAdapterConfiguration
! i- o* U5 Q/ a; |8 G" @+ X   Win32_OnBoardDevice  z; [, S% l' V* @. s$ q
  Win32_ParallelPort
2 O. W) k; O4 ~# L! k  O7 Z$ |6 ]' W7 A   Win32_PCMCIAController
6 j" n: p, X9 {   Win32_PhysicalMemory9 E; i! ?1 e7 f% _9 Y9 G
  Win32_PhysicalMemoryArray5 o/ `0 j" E7 E3 q2 O# J1 q, f
  Win32_PnPEntity+ [2 x' v. W  T4 u9 @! w4 C
  Win32_PointingDevice
7 U" v6 H  ]6 r2 K- A1 Z* h   Win32_PortableBattery
& z. j$ {7 Y. K4 Q. U4 }- @2 T   Win32_PortConnector
; E5 H0 h3 b9 y( l5 g# @   Win32_PortResource
: o4 Q- o, T. I* e   Win32_POTSModem4 d3 O* L9 L: Q8 G7 `$ s# l
  Win32_PowerManagementEvent
7 ^# D. U) \+ o+ ^   Win32_Printer+ R$ G, [: A5 c* ~' F; s. \
  Win32_PrinterConfiguration! V* g: r7 i' t
  Win32_PrintJob7 n+ H  [8 Z8 f2 |4 L
  Win32_Processor+ s, [+ G. i4 Y: F+ Z
  Win32_Refrigeration
2 s) j; f5 M7 X/ E: l9 t9 J/ _; @   Win32_SerialPort
2 }. U) y  o" Z6 C" C4 O   Win32_SerialPortConfiguration
! A+ a  Q/ D/ A7 }0 {& F4 @   Win32_SMBIOSMemory6 S4 ]/ c; z# z% Q
  Win32_SoundDevice* i3 J' O/ ^; D+ [
  Win32_SystemEnclosure. ~4 K2 h7 n7 w$ P1 l6 Q
  Win32_SystemMemoryResource
& z* N* m2 I) X/ }  O   Win32_SystemSlot* D! D  o1 s* h5 }9 u
  Win32_TapeDrive5 D6 K( p6 p3 R  e$ c6 ?. L5 z
  Win32_TemperatureProbe, `2 O: U  i& u# u0 ?# _2 E1 e
  Win32_UninterruptiblePowerSupply- c4 O9 ~+ d' z/ L5 }3 r, I
  Win32_USBController
/ W  O2 a3 u! ^   Win32_VideoConfiguration
7 m0 y7 u; {6 n& Y% e* }# c   Win32_VideoController, ~& a$ A8 ]; I. }) H
  Win32_VoltageProbe8 u: W4 Y5 V. @( m4 G
- D1 v6 o; y, C- n
以上类型(字符串值)通过前面写的函数 GetWmiInfo 可以得到相应的信息, 例如 GetWmiInfo(Memo1->Lines, "WIN32_bios");
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-11-27 02:02 , Processed in 0.023412 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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