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

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

[复制链接]
发表于 2005-5-22 17:04:00 | 显示全部楼层 |阅读模式
  Victor Chen, (C++ 爱好者)7 e2 h* ~' T. h: S5 ~& ]' ^, P( Q6 P
* ?; j/ e6 A; k* I! X

: p/ a* P) s: {/ X. _" ~2 j3 A- S9 v9 [--------------------------------------------------------------------------------% X: q! `- [# K) `3 Y% p
WMI: Windows Management Instrumentation (Windows 管理工具)
+ \" [; i$ x# D- d& o# H, W   通过 WMI 可以获取主板、BIOS、磁盘、显卡、网络等几乎所有的系统信息。
4 N9 r5 u' Z0 |! x   利用这个工具可以管理本地或客户端系统中几乎所有的信息。: j, y" R4 Y  z9 N; d+ `6 W% Q! x' N
  很多网络管理工具都是基于WMI开发的。在 Windows NT/2000/XP/2003 都有这个工具, 在 Windows 98 里面可以选择安装这个工具。
* ~3 f0 `2 Q4 @9 R' E: m6 T/ X6 W, _6 _  X3 f
--------------------------------------------------------------------------------
% Y) m) C0 c( F! u" t! t' {* |BCB 的 WMI 库文件 wbemuuid.lib 由本站提供, 包含在本页下面的程序源码下载里面7 F: ?! b# O/ g1 {  z

$ E0 _* h' d. n--------------------------------------------------------------------------------
' ~  z2 ~+ c4 c" g① 初始化 COM 接口:
; y4 {: d4 @8 a" x: x4 ?) e4 m" L   访问 WMI, 必须先初始化 COM 接口, 在程序的一开始调用 CoInitialize(NULL); 初始化, 在结束时调用 CoUninitialize(); 释放资源。7 ]" \. S; A' }9 A1 B, Z6 D
  这两个函数在 #include <comdef.h> 里面定义。
& H" v0 K3 {$ v' X8 w! y
( X) |% q' F3 W! G- W② 获取访问 WMI 权限:
/ J2 |  A8 [/ ~" K% E/ ^   CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);
$ i+ N4 R: A- \1 C& E$ s6 R6 z3 G   如果这个函数返回 S_OK 获取权限成功, 否则为失败。
% V# {; f2 g" f' I$ q9 K  B% R. W* e- k
③ 通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息:
0 A# x+ X6 h" f5 X2 }/ s   这个函数的参数: lpList 返回信息, wsClass 为要查找的系统信息类, 这些 COM 接口在 #include <wbemidl.h> 里定义。
9 j4 x. d0 i; `3 @) N) f: R; m
$ F  G& p4 f: [# Z% Rvoid GetWmiInfo(TStrings *lpList, WideString wsClass)
( _; `: }1 e8 D, e  q0 V{
% c- G# M, Y6 Z! W$ t2 S  IWbemLocator *pWbemLocator = NULL;1 H' E* @, z; n5 Y! Z+ f. j% h
  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)' p( U+ K; I5 M. f; o7 R6 d
  {3 k7 Q- R7 ]0 |. ?! E. H. L
    IWbemServices *pWbemServices = NULL;6 B. i/ n! i' m* l
    WideString wsNamespace = (L"root\\cimv2");( Y* x4 `# u+ R" k4 Q
    if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)& b' x8 n0 Y* N; d# E. [
     {
3 F" H+ A( P9 a+ H. o+ _        IEnumWbemClassObject *pEnumClassObject = NULL;# m' M) D" k3 I* G
       WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;
6 j! Z8 x1 E3 e) M, {4 ?2 d        if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)' K; U4 q* U4 D9 m! T7 `  E. p
        {: r5 y4 w$ d: s+ U; k5 ~; q. t9 w
          IWbemClassObject *pClassObject = NULL;
4 y- B! V) b. E0 t  N           ULONG uCount = 1, uReturned;0 H" }: y, r  O! d, }/ u
          if(pEnumClassObject->Reset() == S_OK)
- f. \4 b$ X4 R            {
" R' @# A: j5 K4 K$ v1 r* G              int iEnumIdx = 0;. K( R+ V5 p7 G7 w7 J
             while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
& T! {+ C3 E1 ^$ \               {, ^; @3 Q. c7 h/ v1 |  G
                lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");: B2 v  B  V' h& r& i0 u! c
& h  z" D) T5 d- s/ ]4 w& F3 N
                SAFEARRAY *pvNames = NULL;- d  N1 M. z# }2 u
                if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)
* f7 }9 I* D5 ~# x0 V0 ~                  {
' [9 P% a1 T. `                    long vbl, vbu;( E! V8 v4 C6 P* @3 r) ?8 b
                   SafeArrayGetLBound(pvNames, 1, &vbl);
/ o$ x, d' B# H" ^. C                    SafeArrayGetUBound(pvNames, 1, &vbu);
, ^; M! A0 ^, y0 }; r1 [+ a& Q                    for(long idx=vbl; idx<=vbu; idx++)5 e2 x$ h$ K0 X; e
                    {- t2 f" E* I8 h6 F1 g" m- s
                      long aidx = idx;! l9 b9 F: g7 j, f
                      wchar_t *wsName = 0;2 W% d' o/ d  ]+ z7 E
                      VARIANT vValue;) b; s/ n" ]; J( X
                      VariantInit(&vValue);! }5 F; o; T) c( R- X
                      SafeArrayGetElement(pvNames, &aidx, &wsName);+ \4 q8 p  G3 Q1 `9 g. F* d
& Y8 i1 {0 d, E. B9 _5 [3 }" g
                      BSTR bs = SysAllocString(wsName);
* G- L4 m; q* d3 z" W( y                       HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);. I2 i4 i4 X% W
                      SysFreeString(bs);
( b  D; q, s7 E5 _( z& V' ~+ q& h' n) P- T0 P6 D9 s
                      if(hRes == S_OK)$ {& {4 l/ `: L8 f/ K: l2 z+ n0 e
                       {
* Q6 {: `% A0 J! Z* e$ q                          AnsiString s;, m/ Q/ O" j! d& V* h0 z3 L
                         Variant v = *(Variant*)&vValue;% ?+ m% h2 H1 M
                         if(v.IsArray())
0 A- f9 _6 Y3 Q# P. Z1 l7 E                           {8 ]. O; W9 E* n  o4 h5 I$ [
                            for(int i=v.ArrayLowBound(); i<=v.ArrayHighBound(); i++): N9 ?* R6 A' a
                             {
( c) }5 e) J2 T0 [6 C                                Variant a = v.GetElement(i);
; C( k9 y1 A0 K                                if(!s.IsEmpty())
/ C: U# P7 P) p2 P                                  s+=", ";
, I# x2 ~' _' j( s. X( [" s9 U. V4 B                                s+=VarToStr(a);- ^/ M( P2 @/ B* A8 n
                             }" [$ K7 P% X7 j! t8 i) Y  G
                          }
4 P4 N9 Z. p2 l8 w" O, ]0 }/ U                          else5 D( M, ^0 l1 B, c6 R4 i. A- S
                          {9 s) `# n3 `2 C) @& l/ }; z" T9 O& r
                            s = VarToStr(v);& P& G; w* k2 M: Y1 D4 I
                          }
$ g$ I5 \* [9 A3 ~! I% i( z                          lpList->Add(AnsiString(wsName)+"="+s);  ^& c, M/ }3 Z
                       }
- }, G8 [1 r& N" O- k
8 N9 Z, x8 M5 J* y) Q                       VariantClear(&vValue);; z) R& V' X# A' L' B
                      SysFreeString(wsName);! f$ T7 w1 A% U# G* r. R3 ~  v
                    }
0 ?& Z# l& b+ n5 `                  }
6 ~) Y9 l% |$ d. L0 D- g                 if(pvNames)SafeArrayDestroy(pvNames);* L" j9 t7 x; ?; ~+ W
                iEnumIdx++;6 U1 J1 O/ b% J. d# D( F  I7 [
              }
; E2 Q4 q6 d% h" l, o- ?            }
5 ]9 i9 c' L% f) \8 U4 _           if(pClassObject)pClassObject->Release();5 P9 h/ {6 G  E7 S3 z
        }
. `% S9 Z& |$ S. q$ b5 r- Z# l        if(pEnumClassObject)pEnumClassObject->Release();0 t. D. h, H5 `* c4 ]# _: j" @
     }' L9 D2 S5 A/ m* f# x( P8 h
    if(pWbemServices)pWbemServices->Release();# X5 H! J6 u8 ~/ i! |7 R" p
  }. e& i& l$ _9 B
  if(pWbemLocator)pWbemLocator->Release();
* R8 L, ?6 _) b" N1 y4 x}' _8 h% ^  n# ^) u# z- M
//---------------------------------------------------------------------------% \, y. R) ]! T$ ~

, @  d" Y6 J. `0 S// 通过 WIN32_bios 获取 BIOS 信息:. u# y5 |% y3 f0 b) y* B
void __fastcall TForm1::Button1Click(TObject *Sender)' [/ C2 Q; j5 X/ q7 q
{
* d: M7 l' Q% b# V0 Q; Q    Memo1->Lines->Add("================== [WIN32_bios] =================");
/ ~6 q- i' b5 l- d    GetWmiInfo(Memo1->Lines, "WIN32_bios");
3 I3 x' U( Y9 K# O6 t' C7 D    Memo1->Lines->Add("");* t0 y$ p( H8 X! x* R. ~: G. x- P" T
}7 a5 @2 i! \" }0 U3 x! x0 ]* @

# N; B% t) K0 {! j! R- G7 r--------------------------------------------------------------------------------! a6 t4 j( |* f4 j& ?
  J; O; s- M3 h% K' A
WMI 可以访问的信息类型有:
5 C6 P( l& l1 Y$ D& S5 L+ P   Win32_1394Controller
- a" t# A: K$ }4 S+ I& T   Win32_BaseBoard" j' n6 c& L6 r) L3 s
  Win32_Battery
  d# C: E6 n( A: B/ `   Win32_BIOS
; M3 \1 a5 C" {+ u+ l3 V: F4 C   Win32_Bus3 |8 s$ q  t3 }
  Win32_CacheMemory
% b! Y- G- [2 c   Win32_CDROMDrive$ s3 e, b9 B- M2 _  P  e/ H) T
  Win32_CurrentProbe
* _8 f  Y4 ]! `6 O4 N   Win32_DesktopMonitor
) q5 U. h7 R( E0 Z0 ]   Win32_DeviceMemoryAddress
' V3 u9 D. H) S( g   Win32_DiskDrive
, R, Y; t. P* t7 \4 V   Win32_DisplayConfiguration
- q7 `# r/ [2 o6 J7 M7 s* b3 J   Win32_DisplayControllerConfiguration
9 K+ ]- C$ f6 q& @; w   Win32_DMAChannel9 R  o8 g* \) F- U/ c! m$ T1 W
  Win32_Fan6 |. J. h) h: o- l( Y
  Win32_FloppyController
  G, }" D7 e, z2 K   Win32_FloppyDrive
0 ?" U9 p6 C2 v' X8 l7 {3 T   Win32_HeatPipe
+ c6 y6 Y* g1 Z$ h, v( Y/ \" N* _   Win32_IDEController
  _# B" r" P. ?- Z- T) S/ t+ Q   Win32_InfraredDevice" z8 M$ G+ F* t7 x' \8 s& Q) _
  Win32_IRQResource
7 t1 X. Y9 V+ y7 A7 Q: M6 p   Win32_Keyboard
6 F- x" f1 G4 E! V+ u- I   Win32_MemoryArray) A& p5 Q7 K6 m5 o% F6 W
  Win32_MemoryDevice4 u+ t2 O& F- J, }& s
  Win32_MotherboardDevice
1 }3 j4 Y- S% t/ l" J5 W9 k   Win32_NetworkAdapter# q' r, A$ Z2 K7 s( Z: i
  Win32_NetworkAdapterConfiguration/ q: p5 `0 J! |! F* r: E1 E
  Win32_OnBoardDevice
+ a2 @. ]& h( o3 C   Win32_ParallelPort1 q! @8 z5 b) b
  Win32_PCMCIAController
' J( G- R6 `4 @8 }" H8 \   Win32_PhysicalMemory$ x+ J9 ~2 y/ ^* F, ^; |) U
  Win32_PhysicalMemoryArray
6 F7 i& |2 z9 s  h1 c   Win32_PnPEntity  p" l; a- L" o
  Win32_PointingDevice
+ ^. a1 ~& [) _" }0 u  y   Win32_PortableBattery
$ w2 H9 m2 r- Z# p' [. d. g   Win32_PortConnector9 J: q: }5 p9 u5 m* g
  Win32_PortResource
% b' v1 p, i& D+ f: V2 f) ?, K   Win32_POTSModem
% [$ M+ n% |6 I% a1 A7 [  c   Win32_PowerManagementEvent
: U) r% \- H5 E2 [   Win32_Printer
- ]3 c5 n+ d# Q7 T   Win32_PrinterConfiguration$ e3 f- I" X) s* d0 X8 Y9 V1 d; [' C' o
  Win32_PrintJob4 q: A  K' N+ Y% A( O) n
  Win32_Processor& H: u  z+ w* Y8 y& T1 x; z* _
  Win32_Refrigeration
) G# s2 x8 }5 [/ \5 x   Win32_SerialPort* a- |( p! O9 y; L2 X
  Win32_SerialPortConfiguration1 l/ t/ u. ^5 n/ K
  Win32_SMBIOSMemory
$ A1 [& X! l/ K  E$ ?   Win32_SoundDevice, s. g2 G+ j; ]2 @; x+ D" g% j' ~
  Win32_SystemEnclosure* m. }& G0 C0 I5 m  ~- s
  Win32_SystemMemoryResource
( g  R% |2 l% ?8 [& L6 Z# C5 k   Win32_SystemSlot4 B2 A7 {; z) N1 @& H0 C; m
  Win32_TapeDrive
; {' F; a7 r, V5 B" G0 A   Win32_TemperatureProbe# m9 P9 O4 ]6 H8 \  E
  Win32_UninterruptiblePowerSupply
- y$ |! c, ~" X) R' E' a   Win32_USBController
/ ~) \. H" U% P2 y0 I+ w   Win32_VideoConfiguration
4 _* z  Z! A* |8 }! k: m   Win32_VideoController
# S1 X1 L5 C$ t9 v   Win32_VoltageProbe
& y8 _1 Q+ Z2 I1 }" ^7 T. C/ q( R3 E* V# t9 w4 \/ @# U4 O
以上类型(字符串值)通过前面写的函数 GetWmiInfo 可以得到相应的信息, 例如 GetWmiInfo(Memo1->Lines, "WIN32_bios");
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-12-1 11:23 , Processed in 0.018619 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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