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

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

[复制链接]
发表于 2005-5-22 17:04:00 | 显示全部楼层 |阅读模式
  Victor Chen, (C++ 爱好者)
6 X, ]: [7 ~1 v& p- h+ T4 E
! @& F8 l! s, L0 ?5 }0 u; ^; p( C+ N. L# U8 G1 p
--------------------------------------------------------------------------------) k. x2 a5 u, l: ~0 C$ z
WMI: Windows Management Instrumentation (Windows 管理工具)
. A. w4 a) c. l( k& I* d& P3 |6 @9 ?   通过 WMI 可以获取主板、BIOS、磁盘、显卡、网络等几乎所有的系统信息。
( f% ~; G9 C( \1 r8 O) x' I" U4 @   利用这个工具可以管理本地或客户端系统中几乎所有的信息。
9 i/ I4 ^& V" a   很多网络管理工具都是基于WMI开发的。在 Windows NT/2000/XP/2003 都有这个工具, 在 Windows 98 里面可以选择安装这个工具。 , H4 e! l& P; _6 D! ^: z5 K
. H' A/ E2 @( ^+ C% P3 o+ J
--------------------------------------------------------------------------------6 t; X& S# h5 P6 Y1 \, x) D
BCB 的 WMI 库文件 wbemuuid.lib 由本站提供, 包含在本页下面的程序源码下载里面
' J7 I4 o- e7 n* c% C9 H8 A+ ]( `" l/ c. n; G" e' V* N
--------------------------------------------------------------------------------
& E" S7 Z& w: k8 y5 Y1 ]① 初始化 COM 接口:; Z1 w1 d" u- x/ D9 E- }
  访问 WMI, 必须先初始化 COM 接口, 在程序的一开始调用 CoInitialize(NULL); 初始化, 在结束时调用 CoUninitialize(); 释放资源。- f3 p5 e' v3 s! o( R3 U! @% i
  这两个函数在 #include <comdef.h> 里面定义。
% M* V1 H3 t1 M+ N6 d6 D4 `2 _1 h1 `  K9 s( d( b
② 获取访问 WMI 权限:
$ Z8 i/ m; k" Q   CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);) ~! Q: q1 {' b; M: o, g! `
  如果这个函数返回 S_OK 获取权限成功, 否则为失败。
3 w6 q- W4 x. Z& i* J8 |2 C
6 T) X% |" |# J" l! T8 N③ 通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息:
8 N/ R# _) i6 s( b. ^2 ^2 H' I0 w   这个函数的参数: lpList 返回信息, wsClass 为要查找的系统信息类, 这些 COM 接口在 #include <wbemidl.h> 里定义。
+ J  P7 f) S# L, f% u9 b/ }9 D6 I0 q$ y  s4 v, @/ G
void GetWmiInfo(TStrings *lpList, WideString wsClass)3 v$ O; h: x3 v3 o0 p
{
) L/ I8 R3 g# Z2 Q+ O  IWbemLocator *pWbemLocator = NULL;8 s* ^& s( q- H. A
  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)9 j! m6 p- n5 S3 v4 {
  {) Q: q) E1 H* W. Z9 K
    IWbemServices *pWbemServices = NULL;4 M+ W7 Q9 H, s
    WideString wsNamespace = (L"root\\cimv2");  a: B( D2 f% c7 T! U
    if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)
1 G3 K* Q+ H( |6 w" Z9 |      {1 Z- F3 S! R- ?) x$ x. \
       IEnumWbemClassObject *pEnumClassObject = NULL;
' _7 n" \+ c. c        WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;- T$ {1 X3 A$ A; ^, |6 O
       if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)
' l/ _; K6 x( \' F2 ]& s7 X0 \5 ~         {6 v' Q9 s# W; }) `1 Z3 f9 u9 W, d
          IWbemClassObject *pClassObject = NULL;) F( j. [/ s6 U
          ULONG uCount = 1, uReturned;
: {0 I2 `4 k% f6 R" ^0 w0 x# I           if(pEnumClassObject->Reset() == S_OK)
: V% h# n& _& z  X8 w) f            {
! D' y4 N& L$ [- W              int iEnumIdx = 0;
+ @- z6 r( m7 T8 x9 b              while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
! u) R* O4 i, S. Q  V" g% u               {4 M7 @+ h' a8 }/ p! R5 D
                lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");2 ^: V% E- L/ m0 G0 }) R

. p8 r8 {" w. E* M# g8 N& [1 n                 SAFEARRAY *pvNames = NULL;
/ \1 }4 d- s& d& f" h, `2 Q3 \, |7 w% I                 if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)3 C1 t" o7 [# t
                 {
; k0 Z/ S- c8 J) ^                    long vbl, vbu;8 s  C# d4 u8 F  ^7 ?
                   SafeArrayGetLBound(pvNames, 1, &vbl);- g7 a" I. t" H8 X& r1 f
                   SafeArrayGetUBound(pvNames, 1, &vbu);' e7 h4 u( m2 |7 c4 a
                   for(long idx=vbl; idx<=vbu; idx++)9 \7 D3 `& O9 N; ^- Q
                    {9 L4 g! R- W: g2 t+ @; N
                      long aidx = idx;2 b8 I  ?" w  B, ^- Z
                      wchar_t *wsName = 0;
, K; S" e# ^  L  L                       VARIANT vValue;
) `+ [( o$ e) D  k" N5 b                       VariantInit(&vValue);
7 ~. H" |0 q$ x+ M                       SafeArrayGetElement(pvNames, &aidx, &wsName);
& N5 v. I3 H& y" n* V* L: V6 H1 d
+ K1 w& _0 w2 @1 ]9 f                       BSTR bs = SysAllocString(wsName);6 `) m; h, V! R! p, R3 w
                      HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);
* E6 p0 N+ Q+ n                       SysFreeString(bs);9 S4 @- c7 o, Q* K+ M

- o+ V0 p: \) k4 F, N$ s3 q5 u2 g0 G8 R                       if(hRes == S_OK)& `3 V' U4 T# P# b: v5 x3 M# G7 q
                       {
) T4 v4 Z* C, S$ O6 }5 F8 P                          AnsiString s;! M# ?8 ?+ s0 A; l
                         Variant v = *(Variant*)&vValue;4 J: \# ^' S6 J, o6 m( Z) s* M
                         if(v.IsArray())
4 h% E) c% u, g                           {1 G9 |. h! x4 M, e! e5 ?: L
                            for(int i=v.ArrayLowBound(); i<=v.ArrayHighBound(); i++)( \4 A( T+ a! x$ m) P0 l% H
                             {  x5 V+ P$ t4 e; V$ q3 J! V. z# V
                               Variant a = v.GetElement(i);- T# N( s8 _  ^( w) I5 A; u
                               if(!s.IsEmpty())! e: Y+ G: j, ^: \2 q
                                 s+=", ";2 P9 W: D- N: ^5 k# @1 g) t9 [0 H  J
                               s+=VarToStr(a);3 z: d8 o% x) ?& g1 ~
                             }- M8 s. j- ?% y8 {. F2 X
                          }1 Z8 D. f! J. Y  ]. f
                         else+ K" m0 Y6 @2 m2 s9 ^" w4 D0 E
                          {
  ]& `0 r- e, H6 v- A                             s = VarToStr(v);
$ \  O  A! I, q2 r                           }
# N+ x3 [: u! d: W% X                          lpList->Add(AnsiString(wsName)+"="+s);1 Z7 m7 z: O6 U; @
                       }" [  j3 w* W2 E! X1 z3 z2 @5 W
5 H, R  n7 L; J: T
                      VariantClear(&vValue);
& C4 b2 N. u- W3 `8 `                       SysFreeString(wsName);
" L" r8 d9 j: u9 T* }0 }                     }5 m/ {! e$ q, g4 [
                 }/ O/ N$ i  ]9 K  A  E
                if(pvNames)SafeArrayDestroy(pvNames);5 {: z' Y8 Z5 |( C, a6 ?
                iEnumIdx++;
: o8 M* _% d7 S               }
: }0 Q" o% B% p2 u9 _4 H            }2 V. {" F! m) [" E. d5 G$ P0 J7 E
          if(pClassObject)pClassObject->Release();
2 y% t$ N' @: s4 P1 E: Z% A9 e         }
  O2 [) c! o3 i, |$ s1 s        if(pEnumClassObject)pEnumClassObject->Release();* j# a& o5 b5 x5 A* A! l' q" j* Z
     }. g6 X- @2 _, X, [6 {
    if(pWbemServices)pWbemServices->Release();. u- T! g3 U2 }" d$ V" _' ?1 M
  }
. M9 W5 [% D8 {+ F6 d  if(pWbemLocator)pWbemLocator->Release();( i8 }& x7 c) V( d/ ?+ ~& K6 C
}
  I4 {- Z6 {1 q6 q! P9 X//---------------------------------------------------------------------------
% I) I# a" o7 [  Q. b* n
% @1 g! x1 d7 `4 V/ B; A" z/ H// 通过 WIN32_bios 获取 BIOS 信息:8 i4 X. {& [! V; s( M
void __fastcall TForm1::Button1Click(TObject *Sender)
3 v: [* D6 X2 m$ M+ h{: }8 i& r! Y3 s2 N/ U0 i6 n
   Memo1->Lines->Add("================== [WIN32_bios] =================");* W# C2 e$ t; c+ c+ a: C" [
   GetWmiInfo(Memo1->Lines, "WIN32_bios");
0 h7 p" E3 A3 S! Z  X1 I    Memo1->Lines->Add("");0 ~/ P# W0 l0 u+ F* A4 q
}
/ ?/ Y# i/ k* ~2 `5 C
; M3 h' x6 y: t--------------------------------------------------------------------------------
( s' Q6 R2 c2 N( w% q- A) p3 O5 p5 Q9 `0 f( B
WMI 可以访问的信息类型有:
- V% g6 d, Y% S/ m   Win32_1394Controller2 u" K# n: ^8 D2 T% F  e* x
  Win32_BaseBoard5 ~% B1 [9 P5 d
  Win32_Battery' ?+ N0 \1 M% t' j% m5 f: C) G3 F
  Win32_BIOS
9 j9 Q4 c5 n; `: j/ k, W8 O( ^7 W# b6 K   Win32_Bus# Z& s% u( }: }3 w% Z6 d9 F$ c
  Win32_CacheMemory
& }" y& T2 q+ [8 v( d+ J   Win32_CDROMDrive0 Q4 \% a1 y0 k# ~+ x
  Win32_CurrentProbe2 p, W+ C7 l8 j1 A+ d
  Win32_DesktopMonitor
5 X- X- F# x, ^2 L  q% \; W   Win32_DeviceMemoryAddress
5 k7 m$ f# }% ]# U2 J   Win32_DiskDrive& F/ M& ]" R! s( L" a5 K3 M9 i1 G
  Win32_DisplayConfiguration
: [6 O/ Q$ k  q" A# z) P( G   Win32_DisplayControllerConfiguration
1 y3 i: R1 R' |; O/ p$ L& q3 I   Win32_DMAChannel. ]3 A) l- [" d( m' _
  Win32_Fan
' a  s- v- z, f9 G6 g   Win32_FloppyController
0 d1 i! @" X4 e" R# P$ V   Win32_FloppyDrive
* t" z4 o) `/ K- c/ W   Win32_HeatPipe
& A, E( c4 f" `   Win32_IDEController- k2 a" o1 T4 @& m) s5 S
  Win32_InfraredDevice
; O% v8 L6 N1 ^% T! C   Win32_IRQResource( O+ _6 G, |& F1 O9 I2 d
  Win32_Keyboard8 ?6 J, G5 b+ Z! {  d1 T- a0 N( e
  Win32_MemoryArray- B- ?3 X1 x* u3 c# ]- ]
  Win32_MemoryDevice
: Y* }0 k- H- `3 V" \# U' @   Win32_MotherboardDevice
  g& ~' T2 a+ e+ l4 Q$ O, G   Win32_NetworkAdapter
* {- }! ^- l( q   Win32_NetworkAdapterConfiguration
( O  w; f. m7 j6 D   Win32_OnBoardDevice
1 v( s; r( N0 G# _   Win32_ParallelPort
# U/ g0 j+ A) c# B( _/ Y& H" K   Win32_PCMCIAController" g6 F: a/ F9 A) x: ~
  Win32_PhysicalMemory% V, w* c, _. G- g4 k+ o
  Win32_PhysicalMemoryArray5 X" G- L3 U! H$ v3 e' S
  Win32_PnPEntity. ~+ m. x4 }! K
  Win32_PointingDevice
- @' g& x% J/ x6 C   Win32_PortableBattery5 w& R; q' l: O9 F7 ~2 j1 Q
  Win32_PortConnector! S$ R" g0 n* h% a
  Win32_PortResource
) V9 T" j7 g( ]4 \" }  v   Win32_POTSModem+ y8 M( N+ }. W; b& d
  Win32_PowerManagementEvent$ {2 Y/ b6 }# D* l7 {! ?
  Win32_Printer
2 n, B: n/ L! `5 v( Q1 A2 h   Win32_PrinterConfiguration
2 w0 W- ^; Z) `+ L% B2 D   Win32_PrintJob
3 x( D7 }% F7 k# D7 G   Win32_Processor
/ E$ W1 ~$ B3 W& a; }/ ]   Win32_Refrigeration
7 B1 d' Y$ S1 I( Z   Win32_SerialPort
9 L) D' T2 z$ K! B+ [$ ~   Win32_SerialPortConfiguration
% c5 u5 m. F3 y2 f7 E) i* {4 f! @   Win32_SMBIOSMemory1 ]$ y2 k* D$ X) }7 ?: t
  Win32_SoundDevice
% p4 ^0 \/ D) Y, W7 v; V- K/ \   Win32_SystemEnclosure% \, b) g8 I* r+ @3 N
  Win32_SystemMemoryResource8 _7 E9 `  [, [& ^6 q$ G) I: J$ V& [
  Win32_SystemSlot9 e  \) ^3 i& g4 a
  Win32_TapeDrive( g- d  e. H2 D+ d. Y' N
  Win32_TemperatureProbe9 I1 R: K1 O1 H5 Y/ s! _
  Win32_UninterruptiblePowerSupply9 u: l5 F& c( Z' e
  Win32_USBController
, @' @$ K# `/ p7 O   Win32_VideoConfiguration
- x* T9 u( _6 i+ A; V   Win32_VideoController1 N- X% A0 _1 R5 ?
  Win32_VoltageProbe0 {6 F: X9 p5 S" y
* W7 A% p) j, [, C* |4 T  ^
以上类型(字符串值)通过前面写的函数 GetWmiInfo 可以得到相应的信息, 例如 GetWmiInfo(Memo1->Lines, "WIN32_bios");
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-1-28 16:32 , Processed in 0.018229 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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