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

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

[复制链接]
发表于 2005-5-22 17:04:00 | 显示全部楼层 |阅读模式
  Victor Chen, (C++ 爱好者)
- P* w" V3 j6 Z1 t- G  k' K' B5 |0 a+ b
9 _+ b) w* w1 S: e1 V; a) v! A: A
--------------------------------------------------------------------------------6 Q! e8 \' g7 }9 @7 q) ]/ U
WMI: Windows Management Instrumentation (Windows 管理工具)- f4 z7 J& T0 [# n/ x( ~% G
  通过 WMI 可以获取主板、BIOS、磁盘、显卡、网络等几乎所有的系统信息。
' s# L- |# [! [: L7 [1 I   利用这个工具可以管理本地或客户端系统中几乎所有的信息。
( H: U4 L" p& H; e- ]+ a' e   很多网络管理工具都是基于WMI开发的。在 Windows NT/2000/XP/2003 都有这个工具, 在 Windows 98 里面可以选择安装这个工具。 ( I& P5 x5 o6 m; v

* `( ^3 x/ b. i# q1 T" q3 g--------------------------------------------------------------------------------8 F& @1 _  F6 w- V% {6 R, }# p. E: _
BCB 的 WMI 库文件 wbemuuid.lib 由本站提供, 包含在本页下面的程序源码下载里面
/ I4 l. D" M3 K* c8 E* R: l8 d! u! R
7 t5 A: \1 r7 R9 S" I1 j$ @--------------------------------------------------------------------------------6 q& l6 S+ S0 U! B  u% |
① 初始化 COM 接口:; p! T; |+ o4 W# e. I; h
  访问 WMI, 必须先初始化 COM 接口, 在程序的一开始调用 CoInitialize(NULL); 初始化, 在结束时调用 CoUninitialize(); 释放资源。
+ F9 @) p, h2 M( X) L2 j1 I7 R$ Y   这两个函数在 #include <comdef.h> 里面定义。
( E9 c4 \5 r. E" ^- ^5 f& x0 H6 n
② 获取访问 WMI 权限:( ~* y$ H! Z4 Q* n& e, t
  CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);8 Z. O5 J0 N* K, `8 B6 d
  如果这个函数返回 S_OK 获取权限成功, 否则为失败。
$ H. U) S1 e9 z4 V% K/ Y0 m8 J/ ~; T% C" _" [6 g2 J; G8 I
③ 通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息:
0 i5 C  N: T8 C7 z5 ~8 w   这个函数的参数: lpList 返回信息, wsClass 为要查找的系统信息类, 这些 COM 接口在 #include <wbemidl.h> 里定义。
' [  f1 ~1 O" q" ^+ {) l5 E$ E3 F. I, u3 j7 d+ x4 r: G5 h9 H
void GetWmiInfo(TStrings *lpList, WideString wsClass)& z& `( I9 @/ R1 u
{/ I. M# ?, y+ g" B. }: z
  IWbemLocator *pWbemLocator = NULL;4 _- ~4 ?, p; E* O, A' J
  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)2 i0 A" V# m, f& G$ \) h
  {
2 R' N8 u/ p: a( ~  A+ r$ R; X+ J     IWbemServices *pWbemServices = NULL;
% T; G5 D7 N9 M: {     WideString wsNamespace = (L"root\\cimv2");) u# R" A* y, p2 N) j
    if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)
% W; P) L! m5 |* L0 N; p, P      {0 r) k- m$ p: g( M" |. d
       IEnumWbemClassObject *pEnumClassObject = NULL;! K: a) {- R' f1 m" }0 ^
       WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;
$ k) l9 }6 v2 b. e        if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)+ z( w* {' S3 A# `7 v
        {
. ~6 W+ n2 D5 a1 M# J' [           IWbemClassObject *pClassObject = NULL;) T) H2 A! N  U) s5 g3 V
          ULONG uCount = 1, uReturned;4 A/ A8 w) Y: H8 T' a
          if(pEnumClassObject->Reset() == S_OK)9 ^# X; Y2 U, M" S+ |
           {
% _; `" L, @. i8 ^, P1 D              int iEnumIdx = 0;6 ]- F9 P* b0 e
             while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
+ w/ @9 M* |* ]) _* @               {7 b  e8 w' z( i5 q3 G- L; x
                lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");' R6 b- _5 {1 F! J+ A4 h

3 L( P2 e$ ~8 ]5 u( l  E4 _$ A                 SAFEARRAY *pvNames = NULL;
$ Y( C5 d- W& C" Y                 if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)) p$ z9 g! E6 |5 i
                 {
  Z( v8 a" i% ]. h, G4 c                    long vbl, vbu;8 |+ v) H4 G6 ~0 u; o  R- z
                   SafeArrayGetLBound(pvNames, 1, &vbl);
5 F& z% ~7 F( h0 A6 u                    SafeArrayGetUBound(pvNames, 1, &vbu);
( _- o/ p7 F- m5 W                    for(long idx=vbl; idx<=vbu; idx++)
' D& s: |- Q/ x( ~9 E                     {  m, y$ V7 h3 i
                      long aidx = idx;
% \8 @& s0 L3 k/ `  i. \2 M5 j                       wchar_t *wsName = 0;
4 V& v: c& h3 _1 E& D# g/ N                       VARIANT vValue;
, d7 G) V! d/ G1 p/ g                       VariantInit(&vValue);! p. a3 W% U5 q. Z0 k; H/ s
                      SafeArrayGetElement(pvNames, &aidx, &wsName);  l- S; I& K% N- ?$ r/ h
: F1 o/ C' S5 m5 ^' w7 T
                      BSTR bs = SysAllocString(wsName);5 s6 |$ S7 ?: \/ o  T& }
                      HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);
0 X2 ]0 J0 b- u7 u                       SysFreeString(bs);9 l# L2 G" N  c3 v

5 K9 l; c, I3 R  n' Q8 a; Z2 e                       if(hRes == S_OK)
& m8 Z' ]* i4 Z% Y0 C( M                        {  r# T$ Q4 g* H% }# ~2 m' z5 Q( ~4 z
                         AnsiString s;# _$ f/ t  Z7 `* \
                         Variant v = *(Variant*)&vValue;
, W. K8 K7 |4 R2 l, x1 L  t                          if(v.IsArray())
1 m0 ?' h. {6 {( [+ P3 z                           {+ ^& z; k) G+ V7 c) W$ v& p$ i
                            for(int i=v.ArrayLowBound(); i<=v.ArrayHighBound(); i++)6 I( t! e# p7 S
                             {0 z+ f' r8 w3 w
                               Variant a = v.GetElement(i);
; B. C. ?+ B2 a8 K- Z. }' |                                if(!s.IsEmpty())" l% P7 C( Z+ N# i  d, s6 l
                                 s+=", ";* t/ e, A( z( R
                               s+=VarToStr(a);
- h& ^0 {# E: b2 U& R+ \* M# N                              }5 s; m$ Q9 D& |8 p8 {
                          }
7 U. d2 T( W5 ?! G                          else
6 t4 q* [. z+ Q, M$ X, }# G7 p, j                           {
7 X6 i# k. J2 p9 j                             s = VarToStr(v);; `5 }5 n% }; {7 F/ c) ^
                          }
, G6 }) z+ B6 e; _                          lpList->Add(AnsiString(wsName)+"="+s);
, p7 Y0 B8 ~, \$ g" ]% p                        }
, D* X# n5 i4 s; a6 A4 s% c
: d1 k! e7 m( H! y' j                       VariantClear(&vValue);
) F; K( g/ y$ }3 t9 P                       SysFreeString(wsName);$ L$ ^/ l+ B0 V+ s
                    }
( G4 p+ x* \, `, E3 E4 g( i4 k* q                  }1 z  f2 p4 z5 }& _+ j- [7 S$ n1 C
                if(pvNames)SafeArrayDestroy(pvNames);
. }, L+ s0 K( q. C                 iEnumIdx++;
* K/ k5 M3 o4 t0 n/ S) z& I               }
3 a* t4 }8 Z% Z            }$ `, X. Z! w( g
          if(pClassObject)pClassObject->Release();
5 N0 B8 W. S/ [; m         }
% G. Y; y$ u# @2 y8 B  s3 ^, W. l        if(pEnumClassObject)pEnumClassObject->Release();
- [; i2 `) s+ X- L3 {' @) E      }4 t8 Y- E' C" q2 y( y: z
    if(pWbemServices)pWbemServices->Release();" a' o' k* c4 B. Q- W; C& z5 O
  }" T( I1 ]) C2 f
  if(pWbemLocator)pWbemLocator->Release();
" K3 ~" a& A( a1 \}* Y" }8 ]4 ~& A( S  f1 z2 U
//---------------------------------------------------------------------------
9 L6 o* E/ w: h1 R9 E4 C: E! O% t! R+ L# ~8 g7 s
// 通过 WIN32_bios 获取 BIOS 信息:
: b( z+ r. T* B1 L1 |void __fastcall TForm1::Button1Click(TObject *Sender)& y% e9 S3 L4 \" ]; x
{) {& Z) _4 q* x( a  L1 e( C
   Memo1->Lines->Add("================== [WIN32_bios] =================");
, E- W( p4 F7 `: g* r3 k& h$ h    GetWmiInfo(Memo1->Lines, "WIN32_bios");
9 {3 i9 p8 S% ^: c    Memo1->Lines->Add("");. y9 d0 x8 z+ C: t
}
8 p/ e: B% M' f+ u7 r3 u/ [
! u. E% Q$ \9 y4 T: u6 ]--------------------------------------------------------------------------------. `9 \0 ?9 H6 ?- T3 j& U

1 z5 A' j+ B( t1 [* O! AWMI 可以访问的信息类型有:4 X7 b1 w/ h4 e" e
  Win32_1394Controller0 h: M9 |0 X* W" F5 y9 J' `6 t% L
  Win32_BaseBoard$ K& e# b0 I$ n6 {( O: ?, N7 h
  Win32_Battery
) o; ?6 m$ r& k6 `- Z) G! Y; `   Win32_BIOS
1 u5 {+ ~. ~, [7 v) M. V+ ~   Win32_Bus
  s1 g. o) V! W+ {/ O   Win32_CacheMemory8 e# Q+ q+ }+ x1 e
  Win32_CDROMDrive
, O4 b! {9 d' S& o8 U/ ?. G1 F   Win32_CurrentProbe
. |  E& y4 v2 F   Win32_DesktopMonitor( ~5 W$ c' W. }3 O
  Win32_DeviceMemoryAddress
+ ]- f9 L+ R$ d   Win32_DiskDrive7 M* A6 p! r/ @# S
  Win32_DisplayConfiguration
6 ^; f% x: c* C' d   Win32_DisplayControllerConfiguration
4 _2 u1 P+ |! P$ z, Z8 a1 }9 B: C   Win32_DMAChannel( N4 z+ g/ V, t5 E
  Win32_Fan: `0 G7 ]; m0 g/ y& [$ M6 E( Z9 D
  Win32_FloppyController
7 P1 K$ I1 Q; ?! K5 T% I% ^2 {% T   Win32_FloppyDrive
3 f+ Z5 ]  E' H2 I' A2 u# F   Win32_HeatPipe
+ m$ Q' C) v3 n" s2 _   Win32_IDEController
/ m3 q1 q7 j- Z* N3 ^' I   Win32_InfraredDevice
% [6 Q1 C" r/ t8 ]3 N6 v) u8 m4 q5 Q   Win32_IRQResource4 L. L* h, i  K/ o8 B+ D1 F) Z- _  @
  Win32_Keyboard1 e: D1 ~$ O) E3 S% ^1 W
  Win32_MemoryArray
7 E, c& w. M# }$ Y6 D' m+ Y2 O" B   Win32_MemoryDevice: h" b* @* A; X" e6 m. ^6 X
  Win32_MotherboardDevice
7 h8 F: p6 [0 M* a& V2 d- I1 b   Win32_NetworkAdapter- p! `' b$ x, r4 H( N8 ], @! e3 A' O
  Win32_NetworkAdapterConfiguration
9 H0 d& p1 _" ^+ ]   Win32_OnBoardDevice
' c6 h" W5 ]) r5 Y, c   Win32_ParallelPort
+ n0 C3 }  K, o# K4 c1 \   Win32_PCMCIAController& }% j& {1 k. a" c/ i
  Win32_PhysicalMemory
' S5 R: i2 q( C! r   Win32_PhysicalMemoryArray
5 H6 Y& G9 Z" T" |6 a8 R   Win32_PnPEntity3 k! V  o: j6 G" c. k
  Win32_PointingDevice
$ c4 W  m& }. d* \" k; [8 E   Win32_PortableBattery# x! I$ f8 B( d+ V1 K
  Win32_PortConnector3 q9 P" g% s5 c4 _, \
  Win32_PortResource
+ W: {! S' ]( S1 V# Q- j3 i6 k   Win32_POTSModem
5 X3 t, x0 d2 A: g8 b   Win32_PowerManagementEvent1 U/ Q+ k" R. v# e
  Win32_Printer
2 y* O/ y' E. G: j   Win32_PrinterConfiguration. R: I+ v6 O0 x. G7 h4 s/ \
  Win32_PrintJob
8 T7 p- S1 C$ o! t   Win32_Processor
0 c9 k1 k+ A2 x2 E" \& Q- L   Win32_Refrigeration
! o- z% D& `. N- b: |   Win32_SerialPort
, }: \& c' K& l& K   Win32_SerialPortConfiguration
# {* B; i( v. @) a" q   Win32_SMBIOSMemory
' I+ S/ n* B$ O% Y' i  Q   Win32_SoundDevice; b, ^  Y/ j, j/ x. g) b* Y
  Win32_SystemEnclosure- a4 s7 j7 c) y0 l$ q
  Win32_SystemMemoryResource
( U# M  o5 _9 Q# ~: d# c6 ^   Win32_SystemSlot# W  w8 w0 O+ [& K) V5 \: U; D) D
  Win32_TapeDrive
0 J' m5 g1 g- \& F   Win32_TemperatureProbe, R- ~$ G! g% T# Y- J+ n6 d
  Win32_UninterruptiblePowerSupply
- A# _( F" m0 `+ A   Win32_USBController
6 Y9 z1 t2 L' j1 G5 `& ]) N   Win32_VideoConfiguration8 N( V3 @% A( g" j, l  e0 Q
  Win32_VideoController# k& ?: O5 B$ W
  Win32_VoltageProbe
7 Z0 a/ i9 T: {" D, t) n+ V& h
+ g6 N6 c' v8 ~4 i2 r" R以上类型(字符串值)通过前面写的函数 GetWmiInfo 可以得到相应的信息, 例如 GetWmiInfo(Memo1->Lines, "WIN32_bios");
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-12-24 19:42 , Processed in 0.024111 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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