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

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

[复制链接]
发表于 2005-5-22 17:04:00 | 显示全部楼层 |阅读模式
  Victor Chen, (C++ 爱好者)
( \5 B" D1 f9 X; V* \! {
! w# L) ?5 p; B: Z7 K+ \5 j- K' `( S' ^* E
--------------------------------------------------------------------------------
; W) L; P, J% Z3 fWMI: Windows Management Instrumentation (Windows 管理工具)$ l2 w/ e7 d+ I" @/ h
  通过 WMI 可以获取主板、BIOS、磁盘、显卡、网络等几乎所有的系统信息。
. O$ K8 Q9 S/ j, X) m  f. ^4 l   利用这个工具可以管理本地或客户端系统中几乎所有的信息。
% M" ^  ~0 u: d& r, k7 S% u   很多网络管理工具都是基于WMI开发的。在 Windows NT/2000/XP/2003 都有这个工具, 在 Windows 98 里面可以选择安装这个工具。
* U/ K$ ]8 l2 h, i
( x' h. m5 _+ E9 ~  [1 F" U7 K--------------------------------------------------------------------------------& D. Q' O/ B7 |& n( E7 j! D& ?
BCB 的 WMI 库文件 wbemuuid.lib 由本站提供, 包含在本页下面的程序源码下载里面* l9 o* S0 U/ x5 p1 f" b
! p  m  P' b1 T& ^: Y$ J' N
--------------------------------------------------------------------------------0 [' W, n6 g" p+ b* ~5 V
① 初始化 COM 接口:
+ O6 K5 V8 N' p   访问 WMI, 必须先初始化 COM 接口, 在程序的一开始调用 CoInitialize(NULL); 初始化, 在结束时调用 CoUninitialize(); 释放资源。
& B1 y, Q/ u' t5 M" G( S$ ]   这两个函数在 #include <comdef.h> 里面定义。
) u! t1 ?. }( K" \/ R0 q+ j  A6 E# G( A/ ^+ @
② 获取访问 WMI 权限:
' d4 ]2 z7 j+ H( W1 j+ c2 ~# ~& s) {   CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);" r2 t( b' O3 }' E# Q
  如果这个函数返回 S_OK 获取权限成功, 否则为失败。
% \$ z2 \5 Q8 Z6 b9 r$ b! w
* ?1 d2 f7 t' L; Q③ 通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息:
6 G! C& t, Z: O7 X5 f" Y   这个函数的参数: lpList 返回信息, wsClass 为要查找的系统信息类, 这些 COM 接口在 #include <wbemidl.h> 里定义。
3 i! M% }8 f- l
* u7 y/ N3 J$ K; B7 Rvoid GetWmiInfo(TStrings *lpList, WideString wsClass)
7 p5 k! E: q/ q: W. l( g3 ]' ^6 n- i& L{3 M  G% [; L# X' B3 f+ G
  IWbemLocator *pWbemLocator = NULL;3 {! `8 V& F' ~9 L' B0 o
  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)) O1 F8 ?' _8 S
  {) B) ^- v- r; U! H, C; n
    IWbemServices *pWbemServices = NULL;  K/ s, o; s0 g1 @9 D$ q
    WideString wsNamespace = (L"root\\cimv2");
) \/ E; B, k) j3 I9 \8 [( Y     if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)5 K1 m* P" ?3 l1 A8 L1 b, ~7 c1 r% y- R
     {  U& d& Q. _( t- k9 z+ W# Z  a
       IEnumWbemClassObject *pEnumClassObject = NULL;7 M' ~" R! @. t; w+ \
       WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;9 c; H/ _$ l3 m* x) F* v) t
       if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)
  y3 @( L2 E0 `1 ^+ Q( {         {& }: C7 O. F/ c' i
          IWbemClassObject *pClassObject = NULL;
% E+ L, {- p- A, ^           ULONG uCount = 1, uReturned;
1 i) m- _8 L- X  ?! @5 e. z7 \           if(pEnumClassObject->Reset() == S_OK)
( ^- f! K9 d, p/ b' l            {0 h  s9 m& D, G% }
             int iEnumIdx = 0;2 D: A9 z, u5 h; `7 t
             while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)' h9 t1 D  T, E) A
              {
; x% e3 ]/ k8 X8 A! j6 A                 lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");& O% G: N) n" U) ]& b6 [9 ^: d

4 u' Q3 H6 b4 B                 SAFEARRAY *pvNames = NULL;' `; V/ P6 r) z0 o
                if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)
- ]  i; D- _1 y                  {
3 v2 x/ s+ q6 c1 p; z. U, B                    long vbl, vbu;
5 t4 ~5 ?! D- h& L+ E3 S( N                    SafeArrayGetLBound(pvNames, 1, &vbl);  z. Z9 D2 ]; \- S
                   SafeArrayGetUBound(pvNames, 1, &vbu);
8 D0 D7 f6 t8 \  S                    for(long idx=vbl; idx<=vbu; idx++)( o8 C$ H# Y9 {0 w, E( s4 N1 h! h
                    {
8 l) y# e0 t$ S; e3 G( g                       long aidx = idx;5 H/ {3 T3 |. c; [; ]/ h, L
                      wchar_t *wsName = 0;/ T# ^7 {) ?4 c* d$ _+ C' b
                      VARIANT vValue;
2 w' I! d4 v% s5 p) @                       VariantInit(&vValue);% X' E% ^  H, k7 s5 ]4 i! g
                      SafeArrayGetElement(pvNames, &aidx, &wsName);8 C$ `: m9 `, ?/ _# Z
- ]$ C* @0 b9 G$ i3 f
                      BSTR bs = SysAllocString(wsName);
/ [. s# \& g& m- g. I4 ^* F                       HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);
2 `5 a9 \! F) |! K                       SysFreeString(bs);
# ?. U" X5 c# ~& O' @6 f& v& U& J3 M$ L7 j6 m" \& U- ]
                      if(hRes == S_OK)4 X7 k. V% n- a# U; l5 U0 S/ ~
                       {
) y2 h) d0 A* b! Q& M2 o# z                          AnsiString s;
$ {. N7 U0 W, W1 l) q                          Variant v = *(Variant*)&vValue;: I  l1 D6 F5 V7 P0 V
                         if(v.IsArray())# Y/ b7 g2 m) J) v
                          {& `4 O8 @4 _0 l; U2 k
                            for(int i=v.ArrayLowBound(); i<=v.ArrayHighBound(); i++)9 p# f$ j- C  |/ y" J$ K4 k. H  M
                             {7 f8 G6 w+ o! f) D) `6 T
                               Variant a = v.GetElement(i);1 M1 ]" w) D2 Y1 `# H  Z
                               if(!s.IsEmpty())3 E3 ~2 Y+ D  p) s: f
                                 s+=", ";
1 [- c+ x0 _4 F  l  O" z                                s+=VarToStr(a);0 [$ n7 i' }3 ^& e' A+ P
                             }
$ V5 O1 j+ J9 h9 X& F0 c0 r                           }
4 h. Z! Z: i3 Z0 x8 z1 o                          else
4 o" x9 [# {9 ]3 Z/ C8 r$ T                           {% o' ~( X, |  g# `& U* w
                            s = VarToStr(v);% I9 Z8 j3 x5 |- e/ g0 \/ s+ e1 X
                          }7 u) |. Q8 y% v6 l1 f
                         lpList->Add(AnsiString(wsName)+"="+s);$ q3 t+ U: n1 y+ O, {, z
                       }
# ]  g3 X% g4 h. }6 n' j0 L5 z; {1 ]( n, I9 `
                      VariantClear(&vValue);+ A) A5 {0 P2 G- Z- Z+ M1 n
                      SysFreeString(wsName);# p1 ?; [# q# n' C: r9 d
                    }
  m% [' H. V0 r                  }
1 A* U1 Z% x% p8 B- R                 if(pvNames)SafeArrayDestroy(pvNames);# T* Z, i  D( t0 s5 S& S- B2 g
                iEnumIdx++;2 @6 O6 |* {% A7 k% q! ^
              }
8 ~! Y; }- {4 X/ ^            }$ p) @  \: _0 n# F% c
          if(pClassObject)pClassObject->Release();5 @1 y0 D, _6 w5 i
        }! g. Q$ j( h9 u, U- i, W% _
       if(pEnumClassObject)pEnumClassObject->Release();
' S1 S. p' L: w* h* Z2 b+ g      }
8 M! [) l; J7 q     if(pWbemServices)pWbemServices->Release();+ B8 R* y7 ~' z$ N6 ]5 k' V
  }' n8 O: A5 F3 a: J" A' [
  if(pWbemLocator)pWbemLocator->Release();
2 [$ |' X- }2 v}4 c0 W" p3 `. B' I0 T7 V
//---------------------------------------------------------------------------: R5 j( Y: j, ^- a3 s+ b0 O
% \0 R7 w1 o- |1 S
// 通过 WIN32_bios 获取 BIOS 信息:
" D9 o& r0 z' x& W; Z0 Dvoid __fastcall TForm1::Button1Click(TObject *Sender)' i- L0 b) W8 s/ Y7 S
{% @, e( [; S6 R5 v
   Memo1->Lines->Add("================== [WIN32_bios] =================");
4 f6 d! V4 l) t    GetWmiInfo(Memo1->Lines, "WIN32_bios");% y$ W1 Q: f. j# w  K
   Memo1->Lines->Add("");, E8 C7 x4 J4 {) l
}
' H1 ?" D4 S: W9 {1 w% A& A% O$ L, ^+ W
--------------------------------------------------------------------------------
; l% A7 E0 _" y5 B5 H; o2 R
; P) B. r: Z. P. [. ?WMI 可以访问的信息类型有:
- h9 ]: [4 o, K( ~  c- ]   Win32_1394Controller
; a5 V* [" X! v0 e# O, [0 W" R+ X   Win32_BaseBoard
! h8 {; Q4 \  B9 a+ a, o% X+ j6 W2 x6 ]# W   Win32_Battery# R* S5 x! \$ ?$ }% ^; I8 U5 H
  Win32_BIOS
! P6 {; l/ }; q4 u   Win32_Bus* Y4 z; u$ S$ J" w0 o; o" _0 q; ~4 X
  Win32_CacheMemory) z. f9 p7 Q3 _: l
  Win32_CDROMDrive
7 `5 m% ]3 e# v6 b1 n   Win32_CurrentProbe
9 _/ Z( {3 s; W# m   Win32_DesktopMonitor
  d( J3 i9 J* v, Q6 N# ~' X   Win32_DeviceMemoryAddress
1 _9 [  B, i0 D: T( u   Win32_DiskDrive
% M+ A$ t. O2 w- |* g0 z   Win32_DisplayConfiguration
" z, y8 b  T# N" c! s1 I: v6 o! B   Win32_DisplayControllerConfiguration0 q7 c) O1 t  t. @( f
  Win32_DMAChannel
' t3 n, J+ l; |! T   Win32_Fan
6 P" p7 |1 d) c$ C' ~   Win32_FloppyController
! Q' Y; w% h0 i0 `, A   Win32_FloppyDrive
% L1 u, t. V( S; ?% o* Z9 ]7 k   Win32_HeatPipe( @8 W) e. \  `
  Win32_IDEController' W6 k$ p- _8 M- R# z
  Win32_InfraredDevice- ^- |+ ]9 r# \! J, @2 u2 v9 X
  Win32_IRQResource; m  S: X! E* M" s
  Win32_Keyboard
7 l! a$ M# Y6 D, ]   Win32_MemoryArray7 [& V  }0 ~* N1 A
  Win32_MemoryDevice/ r3 b) X0 w/ n# f1 B; K+ l
  Win32_MotherboardDevice
7 G& u8 R7 z* T. B   Win32_NetworkAdapter. q# y# R, H. Y& A# P4 Z0 |1 p
  Win32_NetworkAdapterConfiguration
1 D2 l- w& A2 ]* L5 L& A% ?   Win32_OnBoardDevice
' P. y* O0 y* n% O. j( r, P8 Q& ]   Win32_ParallelPort
! x+ u, B' D! z   Win32_PCMCIAController
' Y" ~) Y. G* _* |; p) M; h) m   Win32_PhysicalMemory- ^0 u3 N- O3 A
  Win32_PhysicalMemoryArray) p7 J+ R) h& `9 }0 A) g
  Win32_PnPEntity  L' G' q/ E( M, g! |0 b
  Win32_PointingDevice
9 K3 j5 B& x$ K9 y! O$ A' V# `3 P* H  n4 R   Win32_PortableBattery
$ h4 a4 W7 C, }( `/ x2 [   Win32_PortConnector
; J6 [. E9 e0 s5 p. W0 @) ]   Win32_PortResource
: F0 E6 `) G) B, w8 S9 U" j   Win32_POTSModem9 Z# Z# O- ]; d# V
  Win32_PowerManagementEvent
) w$ ^3 m& ~5 Z+ x5 C' M   Win32_Printer
" P" m+ m1 }' y$ m$ c3 y! c   Win32_PrinterConfiguration
( [) z  V: `3 r3 p7 N6 P( l- i! U% D   Win32_PrintJob
! [1 ?5 H3 `8 X/ S4 s; D3 ~" D   Win32_Processor9 l) i  {: z+ [3 {
  Win32_Refrigeration
( s$ x' V- u" Y2 Y2 l# G   Win32_SerialPort
# o7 ]6 y$ W' }! z0 W/ O: C& P   Win32_SerialPortConfiguration
% m* \( T$ R: _4 I- @! R   Win32_SMBIOSMemory+ o( H+ W- z6 M
  Win32_SoundDevice
( l  F7 J3 [2 T, {   Win32_SystemEnclosure
$ G' H. Q1 u) p! D( R% y   Win32_SystemMemoryResource0 x8 W$ T" [$ j' h
  Win32_SystemSlot9 ^/ _' h  ?% ]$ g0 J9 z" }( h
  Win32_TapeDrive
5 q0 G- I- L+ a( `. b2 I2 v# d   Win32_TemperatureProbe
3 F4 i, B/ [$ G9 x. e   Win32_UninterruptiblePowerSupply8 I+ [/ g9 `# ], i& W
  Win32_USBController
. ^! ?# N! r! [3 |. a   Win32_VideoConfiguration
5 o* B: C. N6 Y' E0 }4 W   Win32_VideoController" }! \: e) Y1 b. C. \) p" }( n7 t
  Win32_VoltageProbe
! Y4 L( e8 o) X/ b8 n) ~. b: y5 p+ F+ c- R2 `3 V+ p$ z% b$ I$ y* |
以上类型(字符串值)通过前面写的函数 GetWmiInfo 可以得到相应的信息, 例如 GetWmiInfo(Memo1->Lines, "WIN32_bios");
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-12-6 21:33 , Processed in 0.018237 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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