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

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

[复制链接]
发表于 2005-5-22 17:04:00 | 显示全部楼层 |阅读模式
  Victor Chen, (C++ 爱好者)
+ K) [" t8 _3 y6 k
3 G! c9 j/ A3 t9 K2 |5 N1 j3 `0 C/ |
1 W2 x0 s- Y/ ~! K--------------------------------------------------------------------------------
% s5 X& ?8 o3 n4 k8 n: r. {: `WMI: Windows Management Instrumentation (Windows 管理工具)
& m2 J; J& D( P8 d1 k4 K   通过 WMI 可以获取主板、BIOS、磁盘、显卡、网络等几乎所有的系统信息。 # P  Q) s  q8 H; X2 {6 h, U
  利用这个工具可以管理本地或客户端系统中几乎所有的信息。
, r" A" _8 l. X7 |( S  n0 x- l   很多网络管理工具都是基于WMI开发的。在 Windows NT/2000/XP/2003 都有这个工具, 在 Windows 98 里面可以选择安装这个工具。
6 T" P5 w) q+ `3 q
) l! c4 ^0 t+ J$ k0 P& D--------------------------------------------------------------------------------
  s7 _3 k0 {% h6 N0 `) QBCB 的 WMI 库文件 wbemuuid.lib 由本站提供, 包含在本页下面的程序源码下载里面( h+ W1 E4 P. }* A. \
! S$ }+ v* Y0 y6 I
--------------------------------------------------------------------------------- V8 P5 h/ i: ]# P, A
① 初始化 COM 接口:( U' q/ W! B) h$ k% M# [; f* z
  访问 WMI, 必须先初始化 COM 接口, 在程序的一开始调用 CoInitialize(NULL); 初始化, 在结束时调用 CoUninitialize(); 释放资源。
  O6 K5 S, l, R4 H   这两个函数在 #include <comdef.h> 里面定义。7 S: x- `0 t. I

, a' S6 ?$ b2 [( A② 获取访问 WMI 权限:
6 ]# o% i2 b" X3 `* N7 I& F* q   CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);
. t( k3 a. ]" I" y. Q5 u# I   如果这个函数返回 S_OK 获取权限成功, 否则为失败。
4 y3 k( v) ?* e
; b0 d5 |: f( e, a, f/ i$ H③ 通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息:7 z! u( {* N& y' Y) J& D
  这个函数的参数: lpList 返回信息, wsClass 为要查找的系统信息类, 这些 COM 接口在 #include <wbemidl.h> 里定义。
& i$ U# Q2 B4 L) |" [
( `( Z# q% o( h+ n$ ^9 i: evoid GetWmiInfo(TStrings *lpList, WideString wsClass): I. T0 H$ n' S2 M, W1 ^; i
{8 N: M, b9 m/ Y
  IWbemLocator *pWbemLocator = NULL;8 W! k. t7 z" S" I1 b
  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)9 }5 L8 w0 Q* Z2 Z6 o
  {
) ~7 c1 Q! c, E$ s$ w  w  ]( i     IWbemServices *pWbemServices = NULL;
/ r; _- E4 T* q; X' z9 a     WideString wsNamespace = (L"root\\cimv2");
. n: p, L- e# Y& E! L     if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)
# s% v* m6 S8 w; g: H* j- [      {
) `- l9 Y6 l: M3 b' `        IEnumWbemClassObject *pEnumClassObject = NULL;
" N- `6 V/ A7 M/ A2 @' Y        WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;
: m! u4 g9 c% G" R* G4 p        if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)
; P3 v0 q: Z+ t% H2 d         {  D+ j2 W6 @& O2 k5 ]
          IWbemClassObject *pClassObject = NULL;, r0 V5 W. m8 U( z1 P6 H/ D; r5 m
          ULONG uCount = 1, uReturned;
5 f& \* {' {3 V9 G, D           if(pEnumClassObject->Reset() == S_OK)
4 Z- \8 i* R2 c" o8 y! f4 T            {+ |3 q; T3 @4 d  C0 R7 ^! ?; p# [
             int iEnumIdx = 0;- a, l! R  a! R$ e. X8 ]3 M
             while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
% W0 d" H- r8 H( T+ p               {
) k$ n) x* a/ a0 u9 x6 d2 N                 lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");: H% o& |* Q. r# X3 r2 P! {8 L" N

" N( l( K2 X- |% n) V8 o) N( C/ n                 SAFEARRAY *pvNames = NULL;
/ F+ x6 |; ^$ i6 T                 if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)6 U7 I% z/ A) z- U  L9 L; C+ _
                 {# p& n( r$ F6 t% a/ ]: m& p
                   long vbl, vbu;4 w. e; G1 c: {5 t2 L
                   SafeArrayGetLBound(pvNames, 1, &vbl);8 v* M% C  u; l2 w/ c
                   SafeArrayGetUBound(pvNames, 1, &vbu);8 B" M2 o5 _2 ^3 {" w4 ?
                   for(long idx=vbl; idx<=vbu; idx++)
* |9 I5 j- f$ o, T) z% ^2 T5 C                     {
( f4 R1 A2 _8 E: t, }                       long aidx = idx;
9 n) o8 I; X" m' A' B3 g, [. k                       wchar_t *wsName = 0;/ |( }0 g- O. f! W
                      VARIANT vValue;
/ q& ^  O8 B/ ~5 w0 e6 M                       VariantInit(&vValue);
2 u2 w/ u) S+ V- f# B  y                       SafeArrayGetElement(pvNames, &aidx, &wsName);
  G( v3 `3 ~4 y4 P  T$ m
# o: b3 m0 s$ b7 A- ]                       BSTR bs = SysAllocString(wsName);- P3 h' f, R# j% \
                      HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);
5 Z2 W; w" M, d# t  f                       SysFreeString(bs);+ a3 J8 n. D9 v' j

) ^1 @# W, Y' U- e                       if(hRes == S_OK)
1 @1 T" I& Z4 }; [' y" ]                        {
8 i3 h( V. }8 x; Y! \8 ?                          AnsiString s;/ n9 |, P3 y1 N# M" ^
                         Variant v = *(Variant*)&vValue;
1 T& l5 F7 @$ z+ x                          if(v.IsArray())
5 j- m* i. N' s! p                           {( D0 R: X3 r# Z8 @
                            for(int i=v.ArrayLowBound(); i<=v.ArrayHighBound(); i++)
( R: e* f+ \" c" f* \3 p                              {
7 C5 v; k7 Q* W6 D/ n                                Variant a = v.GetElement(i);; t3 T4 Y0 q/ K( ]0 H% r( F: I
                               if(!s.IsEmpty())
) ?, T/ |0 c; ~. l0 L  _6 [5 U2 O                                  s+=", ";
4 V# F! v" d( m, p# t7 n3 }                                s+=VarToStr(a);8 E4 h# T% V4 {) f; Z
                             }8 |- I  T0 b" U$ G5 T0 Q
                          }5 Y2 E% ]7 e( ?& _
                         else
/ W9 C) N  |/ C) r: J5 o: y                           {
: U1 E) c9 J+ H                             s = VarToStr(v);; Y" l3 }  I, j% s7 ]: i" Q
                          }
% ?# n( B! y8 ?+ i* i- @) q                          lpList->Add(AnsiString(wsName)+"="+s);* E: M% N& m# ~1 ]7 ^7 ]9 ]! E8 I
                       }; [5 @/ n( z8 K- }# M5 F( C
0 M7 p* n) B3 S5 s+ _9 O* R
                      VariantClear(&vValue);, B0 ^* w3 F. V4 v
                      SysFreeString(wsName);
% b7 i4 {5 F) W4 l, n) b) J# M                     }2 k( L! |5 J  V+ V3 {2 n) Z. j
                 }, o) M6 [; Y2 P" k6 Q8 \
                if(pvNames)SafeArrayDestroy(pvNames);
0 c: M8 \7 g0 y# u/ r- |, h; L+ |                 iEnumIdx++;
3 u! x# r+ u# H% a& C5 Y7 R               }
9 |6 T  j+ O8 `2 I% D; ]4 _! k9 @/ |- \            }* c$ t5 M* f2 I( ^
          if(pClassObject)pClassObject->Release();
& i& |; s# }9 b- Z# R' C/ m         }9 D. b" ]% ~. X$ z3 }
       if(pEnumClassObject)pEnumClassObject->Release();: H% B) B- Z  v, g
     }! ]6 I# A& P& _6 A' e% {" m
    if(pWbemServices)pWbemServices->Release();$ _- p! W. I9 |7 h8 z3 m
  }4 Q  ]' a% J! {% s+ s0 J/ k& t
  if(pWbemLocator)pWbemLocator->Release();
* H+ H' V0 X5 k0 L0 D0 w5 r, R}* k1 ~% X& |( r6 z4 O& g  t9 E
//---------------------------------------------------------------------------
3 ^/ u3 c8 q% Z: S. J; [6 s, [, }7 n/ }3 x7 u5 s/ O+ H  M
// 通过 WIN32_bios 获取 BIOS 信息:- L- @0 N, A2 @5 Q" f
void __fastcall TForm1::Button1Click(TObject *Sender)
0 d) _! e: L6 o* t# ^5 l! X* x{
  g4 ^: t$ X6 h% W7 m    Memo1->Lines->Add("================== [WIN32_bios] =================");* Y9 ^( q" p/ F( R5 s, e
   GetWmiInfo(Memo1->Lines, "WIN32_bios");  @8 l0 ~8 Y2 C6 ]# W1 Z8 x' X$ L
   Memo1->Lines->Add("");! v/ F2 a5 l7 s! X/ F
}
/ P1 r6 N, g# j4 L
$ o* {$ s( x9 i- U8 \* r) ]--------------------------------------------------------------------------------/ g* |, A' P: L) N: f
! \! @+ J0 P- @, p! p7 m1 p
WMI 可以访问的信息类型有:
. l% i  F$ x9 i: p) ~3 ?4 l" u   Win32_1394Controller
6 g0 m5 `; w7 @, {& H   Win32_BaseBoard
3 k! ~& R# b! v6 X# e' ?   Win32_Battery% w) s6 U! c8 m: D# G) S
  Win32_BIOS
5 ]. g2 \0 b) e2 c' Q   Win32_Bus
/ _2 ?( V* c) W7 M$ v4 t+ G% W   Win32_CacheMemory5 {: h- G1 X$ h, g4 ^1 s% H1 a& t
  Win32_CDROMDrive
2 Q9 A) ^/ Y! \   Win32_CurrentProbe, `" B4 N6 ~3 a5 A- f9 m; M
  Win32_DesktopMonitor
! J5 H. [$ ~2 E6 B, p   Win32_DeviceMemoryAddress
+ c$ D. [) {# o1 Y! k2 P   Win32_DiskDrive
: I9 d1 I5 X- T6 D; w# J   Win32_DisplayConfiguration4 B5 ~( e; K% H
  Win32_DisplayControllerConfiguration
) b1 V$ y, S9 A5 }7 \2 i! G   Win32_DMAChannel% B: g/ e0 g2 m% m
  Win32_Fan
0 b6 z6 L5 D5 C; I5 R   Win32_FloppyController$ W$ ~" G0 n0 O% n5 b9 e1 K8 ]
  Win32_FloppyDrive$ \/ W) P/ ]4 s3 r( K
  Win32_HeatPipe# ?4 Y5 Q. m, H9 A
  Win32_IDEController% y* J- n; }7 ^$ I: N0 `# d) S2 ]2 V
  Win32_InfraredDevice
' L& Q8 `( l  |   Win32_IRQResource
6 [2 D' X# B. d1 S. d5 N# S   Win32_Keyboard" N0 R$ z3 p# A$ P1 X( S* n
  Win32_MemoryArray% c* S. Y" j! [
  Win32_MemoryDevice4 t( k( S- i3 c0 U0 Z4 x* m* I
  Win32_MotherboardDevice
" q# ~; O0 H% T$ {& m( M3 |6 w6 t3 H   Win32_NetworkAdapter
( q% c& L- k# A/ N% z   Win32_NetworkAdapterConfiguration
* i$ S8 z; a% R& Z   Win32_OnBoardDevice2 V  q6 @5 ~, q& A& a+ f5 E* g
  Win32_ParallelPort! L  I; V8 M0 o9 g6 K6 S
  Win32_PCMCIAController
4 U4 v, Y2 \' R' J8 [7 z4 K8 v   Win32_PhysicalMemory
# `; X% w5 A' H$ T3 b   Win32_PhysicalMemoryArray' d& F+ R# ^: F" o0 @9 p. ?
  Win32_PnPEntity) L' N/ A* p( ^6 |- d% y
  Win32_PointingDevice7 E2 D2 o; F0 _
  Win32_PortableBattery
, C" d& j; K" R' J$ Z9 d   Win32_PortConnector
& u7 H' ~1 @# ?: ]" q   Win32_PortResource
+ \4 @& d' Q8 t7 a   Win32_POTSModem
. H  h' P5 {. d, F" g) H% H3 I   Win32_PowerManagementEvent% A5 ~) `; y, `* U1 s
  Win32_Printer
8 u8 q6 {" ^8 ]7 ~  T' f: P6 K   Win32_PrinterConfiguration1 E6 p+ u/ d. K8 }5 }* W# ?
  Win32_PrintJob
7 C& X: K# C2 L   Win32_Processor0 O  C( H; F" R
  Win32_Refrigeration
4 F/ e3 I5 ]) B$ Y   Win32_SerialPort2 B: w8 ^1 {( U2 z& q; Z! }. o
  Win32_SerialPortConfiguration  F$ M  O* J! c
  Win32_SMBIOSMemory+ B- P+ ?# J8 Q/ J' `6 v
  Win32_SoundDevice( q1 E& F5 y& R" b5 A! p
  Win32_SystemEnclosure" _% H- S9 n9 _+ Y
  Win32_SystemMemoryResource
5 p8 o+ j, c/ ?6 ~3 ]) g) @   Win32_SystemSlot
( D, [9 \4 L- k; k' q( p1 U% h   Win32_TapeDrive: d% j1 f$ A3 N! X
  Win32_TemperatureProbe/ l$ |% @5 m7 k/ A) y8 }$ W
  Win32_UninterruptiblePowerSupply
& ^  g8 k0 x2 w/ U   Win32_USBController
! p; t/ ?1 X% m+ w1 m' N   Win32_VideoConfiguration! _. L! G) d3 }7 `' N
  Win32_VideoController0 l5 q3 @" [' p$ E. M
  Win32_VoltageProbe
9 Z$ L; u# [; ^5 T% i3 R
1 S( G" F* d7 @- b以上类型(字符串值)通过前面写的函数 GetWmiInfo 可以得到相应的信息, 例如 GetWmiInfo(Memo1->Lines, "WIN32_bios");
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-1-20 05:02 , Processed in 0.018909 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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