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

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

[复制链接]
发表于 2005-5-22 17:04:00 | 显示全部楼层 |阅读模式
  Victor Chen, (C++ 爱好者)
; `( s+ o. c$ ]* _* [9 k8 ~- {' P3 R& p5 w- v/ u
) Q( ~* Z5 {' `+ ~" e" k3 t
--------------------------------------------------------------------------------* H: A1 Y4 q- U& A% Q& Z1 c
WMI: Windows Management Instrumentation (Windows 管理工具)$ Q& r5 n8 L& g" n
  通过 WMI 可以获取主板、BIOS、磁盘、显卡、网络等几乎所有的系统信息。
: p# S/ g( F6 z# f5 V6 _   利用这个工具可以管理本地或客户端系统中几乎所有的信息。
) u  W' `, G2 {! l* H   很多网络管理工具都是基于WMI开发的。在 Windows NT/2000/XP/2003 都有这个工具, 在 Windows 98 里面可以选择安装这个工具。 6 u# Y) ^* C* O& i! e1 N

5 ]1 k, ]$ J6 z8 f1 I& |--------------------------------------------------------------------------------
9 z3 t' ~' H- g3 uBCB 的 WMI 库文件 wbemuuid.lib 由本站提供, 包含在本页下面的程序源码下载里面9 ]/ I& Z7 ~4 u6 g( H/ K; B

- ^! B, a: D- s; i--------------------------------------------------------------------------------
) z' I% _" j: c& ]* U  m① 初始化 COM 接口:3 ~( s% F8 s) N6 K4 _; `: `
  访问 WMI, 必须先初始化 COM 接口, 在程序的一开始调用 CoInitialize(NULL); 初始化, 在结束时调用 CoUninitialize(); 释放资源。( ]( ^) p4 K$ M* e! [2 U; G
  这两个函数在 #include <comdef.h> 里面定义。7 Z8 h0 Z, a; \0 O

* U  w" T- O1 v1 F& e* {9 z② 获取访问 WMI 权限:; T( U% i" a0 W$ C- @
  CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);
' b( L: K/ v  [* w" N6 i% ?   如果这个函数返回 S_OK 获取权限成功, 否则为失败。
* }+ J! O" S1 g% }3 ~. T- X9 U3 m/ O. B1 j/ l& a" u
③ 通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息:& F& @- [' _& Z6 c* r' F$ d
  这个函数的参数: lpList 返回信息, wsClass 为要查找的系统信息类, 这些 COM 接口在 #include <wbemidl.h> 里定义。6 k- y1 X1 V  C' g1 f  y) Y% ^$ q

8 d' l* n7 A; H% hvoid GetWmiInfo(TStrings *lpList, WideString wsClass)
3 o1 ?3 g" u' T- A3 J% t$ u/ f0 r{; R2 ~. v( {- S. Y2 |7 p
  IWbemLocator *pWbemLocator = NULL;" n3 u. m* E; y/ b/ {9 u
  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)
3 i- N3 B6 N0 l3 L0 e& c   {6 I$ G( X2 S/ _+ W6 l: X& w% l" O
    IWbemServices *pWbemServices = NULL;
% Z5 Q5 ?9 ]2 @3 V9 y( q     WideString wsNamespace = (L"root\\cimv2");1 @- C2 |7 I; e/ \& _) O
    if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)
+ Z6 ~( t. R# W% X- t7 `      {0 ?6 R- `/ _8 O) f+ Y3 h2 p( C# k' L
       IEnumWbemClassObject *pEnumClassObject = NULL;: E2 R- d  C& ~$ \
       WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;
5 l, Q+ D: F+ W* T! H        if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)2 b, w( K$ Y$ \) r
        {
$ F8 M0 A+ `; S           IWbemClassObject *pClassObject = NULL;
' f1 a8 ]7 L1 @$ @2 k: J           ULONG uCount = 1, uReturned;) z* F$ T0 x! i6 }
          if(pEnumClassObject->Reset() == S_OK)
+ _6 D8 L% a5 [' H  f            {
; b2 O" u- m2 H              int iEnumIdx = 0;9 D% T: w" b" n4 \. ?
             while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
7 Q2 ~3 x; o* P# o& ~2 H               {
# O  z* d- v) I5 l; j( V$ E9 o                 lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");& V+ C: L, X2 o# }  F- R5 d) k
+ g5 }  I/ S) Y6 A3 t
                SAFEARRAY *pvNames = NULL;
9 w: D5 r3 g7 M) E                 if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)
0 h0 d+ }5 p; `/ z$ ^9 B+ d" |                  {$ c5 x/ n( z5 h+ t. ?
                   long vbl, vbu;
8 {( [; p' `7 t) y9 @                    SafeArrayGetLBound(pvNames, 1, &vbl);
$ `* A- X: ?, Z6 I5 b: b0 M                    SafeArrayGetUBound(pvNames, 1, &vbu);" I- i8 Q+ ?. p4 b! ]9 W/ `7 P
                   for(long idx=vbl; idx<=vbu; idx++)
9 Z8 t) \' q5 r7 X+ c8 g                     {
' a+ H8 x0 N5 R4 J, E) X                       long aidx = idx;' Q& Z" Z: z/ ]( Y7 H; u
                      wchar_t *wsName = 0;1 U7 G8 i& u3 y/ d$ u. i0 L  W
                      VARIANT vValue;3 e" @1 ^( b+ |) u7 P/ ~# b$ Y. ]
                      VariantInit(&vValue);
1 A  W, X3 s/ ~: b# Q                       SafeArrayGetElement(pvNames, &aidx, &wsName);. x( g+ ?/ l1 E+ b* H- p: I
( \3 o# ~  I0 s: D, X" g4 \
                      BSTR bs = SysAllocString(wsName);
: ~: Z3 n& S' i" q% {                       HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);+ z& \9 ^+ Q% y. b* j9 D: [
                      SysFreeString(bs);/ k% ~% A$ D/ Y( p

9 @4 i2 h9 [5 }/ E. y* g                       if(hRes == S_OK)
4 m9 r9 R$ g& p# j, R0 c                        {' J1 {# v( S# y( W
                         AnsiString s;+ ^4 B8 w& ^- `' Y# _& x$ K
                         Variant v = *(Variant*)&vValue;) M0 v; K" X) y4 t
                         if(v.IsArray())
# p% A! J& q9 W0 p( w5 T                           {3 K) n& k: d! O
                            for(int i=v.ArrayLowBound(); i<=v.ArrayHighBound(); i++)
2 Y" _, X- e. q9 a/ A2 w                              {$ t5 w% ~; J8 T4 R0 Y# D
                               Variant a = v.GetElement(i);
/ C5 E+ z1 p  }1 L) p# @' T                                if(!s.IsEmpty())3 W" J* S  y* m9 \9 _: Y
                                 s+=", ";' I; R8 v: @* `( ]" X( s
                               s+=VarToStr(a);
5 i. @2 R# z$ l% ~4 Z! t                              }
5 ~1 ^# x: Y9 t0 g0 ]: M                           }3 p6 |! u" p4 Q* U$ q- j
                         else
. p' U6 g; V* W                           {
( x- v/ R! \, s4 y! C                             s = VarToStr(v);
2 y3 P5 U4 _4 R8 k2 G" z! p' c, i                           }
* c: L& j2 }* d2 S+ N7 r; I- t                          lpList->Add(AnsiString(wsName)+"="+s);" l% i  F) L2 |7 ^- @6 v/ K
                       }+ V* R  V; I# T" j0 R/ D, f

% E3 f* u4 w5 P! y% M3 G& N; _* P                       VariantClear(&vValue);
8 l6 f1 c% M% ?+ j% K  f9 Q                       SysFreeString(wsName);
( U7 c* c2 e& B0 M' I2 n                     }* ^/ U, H* x1 L
                 }0 [; c( }, b7 m: z+ d5 Q
                if(pvNames)SafeArrayDestroy(pvNames);( T3 O* `/ o, ^! |
                iEnumIdx++;
# \+ a$ F, ~  L6 O               }
- w6 S0 S6 W% v6 Y$ w            }4 Q% y1 W$ Y4 p! o1 F+ d
          if(pClassObject)pClassObject->Release();* ^4 `: ?" n$ t& |  a+ r6 t
        }+ ?2 B6 u1 y$ ~8 R  |8 `
       if(pEnumClassObject)pEnumClassObject->Release();
& d* n, {. k3 G  G6 T      }9 o7 o1 V4 ^' Q- I
    if(pWbemServices)pWbemServices->Release();$ E6 g( P1 ^7 K0 D" y
  }  q+ S  M6 {5 V  d# o) \3 {
  if(pWbemLocator)pWbemLocator->Release();7 }6 y4 y# }+ `$ j6 I
}  _; x  f. O, x
//---------------------------------------------------------------------------- K. q; y% S: n9 B& m# C% v
/ l1 I! E( d5 U- X
// 通过 WIN32_bios 获取 BIOS 信息:
! D# Z" P8 x' ]& Q9 Q& V- uvoid __fastcall TForm1::Button1Click(TObject *Sender)
$ z4 p6 z6 ?/ t6 n* J+ b3 V{
2 K3 t4 i* \& W2 k1 U! F    Memo1->Lines->Add("================== [WIN32_bios] =================");/ Q: |  {$ v/ R0 w/ I
   GetWmiInfo(Memo1->Lines, "WIN32_bios");) l0 ~( c3 g( b" [
   Memo1->Lines->Add("");
% i9 t0 e6 v+ T2 ~2 F6 r; i}, N  W4 J5 V4 n$ V" J
& ?# R& t5 u( s
--------------------------------------------------------------------------------
! K  |! v9 u0 Z- V& t4 C! i, [' A  b3 w# ^1 |1 P
WMI 可以访问的信息类型有:- C1 D! J  \2 M2 t( @! T
  Win32_1394Controller
2 b" b2 b0 D; R- a  L$ q7 v   Win32_BaseBoard' X7 E9 N# Z. J* M7 r1 F& Y" s
  Win32_Battery
/ v" W' t: R( C* `   Win32_BIOS/ r1 n1 r# F% ~; d6 ]
  Win32_Bus  V0 K; o! k: r( |5 G) l2 B9 u
  Win32_CacheMemory
3 p- t0 y& c: ?  W   Win32_CDROMDrive
) h0 O; C: `9 e; ^: c# }: R   Win32_CurrentProbe8 m+ G6 V' W0 b/ m
  Win32_DesktopMonitor8 N+ ]; L1 j: u; G: ^
  Win32_DeviceMemoryAddress
7 F1 s" l4 s* u5 s- K( |) c   Win32_DiskDrive
3 J2 }& z9 d+ x, F7 N' ?$ _! }   Win32_DisplayConfiguration$ n5 r7 `  q; z7 T# E: ]' `3 c
  Win32_DisplayControllerConfiguration
3 {8 F) c$ m, A3 [# h/ K- y   Win32_DMAChannel- q9 G6 }' [6 p7 g6 {# G
  Win32_Fan" r# @1 Y8 Z; w, O/ h* r- b
  Win32_FloppyController
8 f0 W  R# r  m2 E0 N   Win32_FloppyDrive/ o6 g7 b" n4 M0 d- C; J
  Win32_HeatPipe- O6 u. K1 l  O
  Win32_IDEController" o$ g! g1 T9 T# k! j' t& z
  Win32_InfraredDevice
7 r6 U  W8 k) n% T   Win32_IRQResource3 ^& [9 H8 Q# H, i
  Win32_Keyboard
% X  l& d$ {/ S1 p# |   Win32_MemoryArray
! T0 a1 j& C" E6 Z" u   Win32_MemoryDevice9 m  X2 |% W& o( `4 I) q
  Win32_MotherboardDevice
/ ^* g. g3 y2 W, N/ Z: _6 y$ q7 _   Win32_NetworkAdapter: Q$ ~* ~0 Q% D# ^+ I+ i( z
  Win32_NetworkAdapterConfiguration
& t! h5 [# H/ d   Win32_OnBoardDevice
% V+ [+ ?6 M1 _+ g' O   Win32_ParallelPort
1 F, d2 P* S* U8 Q* ^   Win32_PCMCIAController
/ D4 \$ p$ {$ }7 s$ ^: ]% [   Win32_PhysicalMemory
3 c0 Q) x6 m  K$ s7 A* [   Win32_PhysicalMemoryArray
  B5 r1 H, ^; b' E, c   Win32_PnPEntity' r! \5 I3 K  f2 Z- @) `# X* t: B& i
  Win32_PointingDevice
; d( `+ V" H. g9 H7 ]4 p/ L' l( o   Win32_PortableBattery: k$ p( A& y" e+ x2 F1 L8 c
  Win32_PortConnector
7 x/ n' P; M0 b7 N   Win32_PortResource/ T- X, ^0 W0 `# c: b) D" M. v( l
  Win32_POTSModem
) H; H! h; y% ~2 B: ]  w3 O- |8 x7 i   Win32_PowerManagementEvent2 N. V# [+ |+ J7 {
  Win32_Printer
$ a: |3 `" ^2 S) R3 y, _% r   Win32_PrinterConfiguration2 G( o# @! J" @$ |  k' S$ S
  Win32_PrintJob2 l; |# @' e% j! F- [
  Win32_Processor
# O6 s  \2 o0 h   Win32_Refrigeration. |7 P! v* f1 _* p' @$ D2 b* d
  Win32_SerialPort
3 U, K& O. u& a0 y0 B( t/ Q   Win32_SerialPortConfiguration
( B. b  W( O* I/ D- _0 ^   Win32_SMBIOSMemory
3 U7 j2 J' R* A: Z+ ?# f2 I! z7 L( r% ?& y   Win32_SoundDevice
5 d, S* ~; x* @1 q( ]0 @. N* S   Win32_SystemEnclosure. I! \1 g: A6 E) g
  Win32_SystemMemoryResource
1 g) u7 G4 [. P2 {/ A3 _   Win32_SystemSlot
5 @/ N$ Y' T* _6 C! {0 I' m   Win32_TapeDrive
+ R1 R! \0 p! i9 a7 |; K8 U   Win32_TemperatureProbe0 e3 N; Y0 J; q/ C5 x) h
  Win32_UninterruptiblePowerSupply
$ y# J* L9 {3 p3 A   Win32_USBController
$ V$ E  Q. T5 ?( i   Win32_VideoConfiguration
4 p+ P/ N6 p5 b; w& X   Win32_VideoController
6 L9 t6 Q* Y) @- z: P   Win32_VoltageProbe
# j' a" C% P3 s+ `- U0 }& b" ]7 x& g; x3 W. Z" R* x
以上类型(字符串值)通过前面写的函数 GetWmiInfo 可以得到相应的信息, 例如 GetWmiInfo(Memo1->Lines, "WIN32_bios");
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-2-2 21:10 , Processed in 0.018787 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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