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

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

[复制链接]
发表于 2005-5-22 17:04:00 | 显示全部楼层 |阅读模式
  Victor Chen, (C++ 爱好者)
* u2 ]& z$ R2 t% n, I. B5 M2 ?8 c0 Y# U) a) X9 ]7 f$ M" I
* `' l3 i; e2 o4 w/ i
--------------------------------------------------------------------------------
/ k4 Z3 }4 A  K  eWMI: Windows Management Instrumentation (Windows 管理工具)
; c+ t: ?5 l1 _6 I1 n8 c   通过 WMI 可以获取主板、BIOS、磁盘、显卡、网络等几乎所有的系统信息。 & o3 L+ g* C. {
  利用这个工具可以管理本地或客户端系统中几乎所有的信息。/ ~' n" J* I* ]2 n4 [5 k  d4 z
  很多网络管理工具都是基于WMI开发的。在 Windows NT/2000/XP/2003 都有这个工具, 在 Windows 98 里面可以选择安装这个工具。
' {: f' p" m0 }7 M4 u  O$ Q1 z8 ^- K; D
--------------------------------------------------------------------------------
" ]$ q: p$ T/ G* W2 HBCB 的 WMI 库文件 wbemuuid.lib 由本站提供, 包含在本页下面的程序源码下载里面
5 n. j& @8 x- {3 i" Z7 z
$ {7 x: X3 @0 u0 p--------------------------------------------------------------------------------
& g( X6 b& j- p: U: c& o  ~* O① 初始化 COM 接口:
& x' U; }6 C$ ]; Q8 l& c; n   访问 WMI, 必须先初始化 COM 接口, 在程序的一开始调用 CoInitialize(NULL); 初始化, 在结束时调用 CoUninitialize(); 释放资源。
4 y) O) O+ {  ?7 @8 n8 ?7 C$ ?, P   这两个函数在 #include <comdef.h> 里面定义。
1 l3 d2 G& L& A% f/ @* P5 @: B
+ Z- ?6 `2 r5 T) U8 c0 Q② 获取访问 WMI 权限:
+ m) V8 U$ i: {' r4 A3 `   CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, 0);
* M* c  W# J/ W' z" _   如果这个函数返回 S_OK 获取权限成功, 否则为失败。
1 I# S- r1 ^" V# v8 r; _" b* K. |9 i% ]) d8 n3 e8 z- S) B  \. Z
③ 通过 IWbemLocator 和 IWbemServices 这两个 COM 接口访问 WMI, 获取系统信息:( S2 ^) F& H& c5 `% P( b
  这个函数的参数: lpList 返回信息, wsClass 为要查找的系统信息类, 这些 COM 接口在 #include <wbemidl.h> 里定义。% d& `( Y% S6 x
; A8 {  E$ C) j- V
void GetWmiInfo(TStrings *lpList, WideString wsClass); j- F: ^; a* H3 x, n% a/ O
{
5 W4 T. ^0 _, a) e  p2 n# M" Y  IWbemLocator *pWbemLocator = NULL;( Z* C. z0 d3 I% _( c: V
  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)1 A5 G. Z2 W0 ^3 Y* O" l6 J
  {; e+ {9 ?8 l+ l1 [& [
    IWbemServices *pWbemServices = NULL;! o) Z1 u+ Y9 ~. N9 |
    WideString wsNamespace = (L"root\\cimv2");
+ o% @7 b4 O/ C1 h( S     if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)! m) E: ~: a0 q4 a) T% b
     {$ W: x$ R) o& P) H4 v) d# C
       IEnumWbemClassObject *pEnumClassObject = NULL;
8 x  d4 C; z) P' ^5 z- }, E9 ~3 P0 _        WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;' b9 s# y4 M$ t* Q& {
       if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)0 K' @5 T1 q  C4 A
        {
/ u# _5 y, u% r1 a) ~           IWbemClassObject *pClassObject = NULL;
3 ?7 k& y2 F; d0 H+ i( N           ULONG uCount = 1, uReturned;) v" P8 q# B( a+ x8 ^' E8 U0 l
          if(pEnumClassObject->Reset() == S_OK)
2 r9 I: a+ c! E2 ~            {4 o" T+ V+ \# a  c9 U; H
             int iEnumIdx = 0;
9 @$ O8 V: }* K( ?5 }1 r* S  l              while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)! \1 L# _% y$ n& ~
              {) {" c# U/ ?: b4 v% D
                lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");
* C- Y. Y; }0 Y2 r% W
* p  G. t( b3 N  m0 ~1 ~                 SAFEARRAY *pvNames = NULL;
9 ?( k  \3 Q  V9 U2 P                 if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)! _0 z( \# U5 ~+ |  {
                 {1 Q' }) ?$ k8 x3 ]3 x0 L
                   long vbl, vbu;
4 y  ~+ n( ?; i; X* h1 q                    SafeArrayGetLBound(pvNames, 1, &vbl);5 M$ R( ~5 d; I* G
                   SafeArrayGetUBound(pvNames, 1, &vbu);
  L# I: ]1 @' P; x- M/ m                    for(long idx=vbl; idx<=vbu; idx++)6 S/ C1 h0 S# {* y3 h; L
                    {
6 ~( r+ X$ ^- _5 G                       long aidx = idx;
9 n, C' A& m( T" u7 ~                       wchar_t *wsName = 0;
/ p+ Q1 z; _! e8 g/ V8 w" {1 ]                       VARIANT vValue;
* H, \: W( W8 A* t' M2 d* j$ F/ Q                       VariantInit(&vValue);
! H; U8 R7 e/ l) Q! k% `                       SafeArrayGetElement(pvNames, &aidx, &wsName);- f1 ~; _/ W. O4 U2 p6 K7 ~# z' U

- c# ~. G5 e& p: J                       BSTR bs = SysAllocString(wsName);  c/ F; o/ o' r6 q) N1 I# B/ ]/ Z/ B* Z9 e
                      HRESULT hRes = pClassObject->Get(bs, 0, &vValue, NULL, 0);
& [- p8 {* Y% b                       SysFreeString(bs);) o7 ^% J$ ^* o2 t$ a2 P
# R% G$ b) r% M6 s. b3 S
                      if(hRes == S_OK)/ o3 m1 K: t0 M% S
                       {# ~: c5 y7 D+ X5 a5 Q$ ~0 P; D. R
                         AnsiString s;  P. |4 O+ c) B1 p
                         Variant v = *(Variant*)&vValue;. C2 t: t2 U" F( M. B- n/ Q
                         if(v.IsArray())- o- v: L3 F% s9 c6 r
                          {
/ D3 q1 Q. a5 J5 ]% n1 W2 V                             for(int i=v.ArrayLowBound(); i<=v.ArrayHighBound(); i++)# R$ t- L* w9 D0 g
                             {/ T& j" Q, z0 H4 I* K
                               Variant a = v.GetElement(i);
! @% z. k- e8 f% P$ ~% N                                if(!s.IsEmpty())+ v1 K- f8 a1 R+ Q) x4 P8 u5 s, b
                                 s+=", ";
9 r+ \# i  K  I: Y  y1 }# s                                s+=VarToStr(a);6 z' e1 |7 F+ s. ]' c! m; Y
                             }
0 B, O  Q( C: f                           }
: U0 v4 Q+ t9 d3 |6 j* ~                          else) h; f4 \+ X& ?5 Z: ]0 v
                          {
  a5 v; `% b6 \2 \. m                             s = VarToStr(v);# C; W1 X7 G" J+ h6 I
                          }
/ x" x% n3 ~& o$ s                          lpList->Add(AnsiString(wsName)+"="+s);1 F8 K7 [% Q- x# F' j: G. g: f! s: c
                       }
5 O9 G0 {- l' ?4 W) N
# M8 @2 d" W9 w( G, {6 Q                       VariantClear(&vValue);
8 {$ S8 C! t( i0 r; h3 i                       SysFreeString(wsName);
* c/ r8 C* x8 G7 b; A, s) k" @                     }
, }* m* ]4 ]# l) K; y) D) ^                  }
1 W- q& w8 t* C- d                 if(pvNames)SafeArrayDestroy(pvNames);" s: s. }$ g/ x# `
                iEnumIdx++;5 W: \+ N, @/ Q; B4 Z: `
              }# O* w$ k9 D+ q$ [- Y$ C  |$ G
           }
' F: g/ Z% ]# W" o2 ]           if(pClassObject)pClassObject->Release();
0 @8 \- [7 e$ \8 r. J         }
% O6 u; W: H6 m+ A        if(pEnumClassObject)pEnumClassObject->Release();
) ~; Y3 t$ n; p6 o      }
7 f' v$ E! ~6 |% w6 f' V& [& t" C     if(pWbemServices)pWbemServices->Release();
& Q  o( F" n5 }; b, F$ o   }
0 i$ n. M" _1 Q7 R# o' Q2 w, f" S  if(pWbemLocator)pWbemLocator->Release();
1 ^% n3 a# e/ X$ v. i}2 Q: j! A. W5 e+ f
//---------------------------------------------------------------------------
) B1 j" r1 ^- z& R4 i
% l0 K, t0 Z  c4 Y* t- p// 通过 WIN32_bios 获取 BIOS 信息:
0 [$ x6 v+ h+ _, x8 w: L7 n& u. mvoid __fastcall TForm1::Button1Click(TObject *Sender)! P/ d9 D5 N- X" S8 K2 c
{8 [) i; o% c' @8 U8 P0 z0 q8 g
   Memo1->Lines->Add("================== [WIN32_bios] =================");* i! j) b. ]) l1 d8 a# _3 P
   GetWmiInfo(Memo1->Lines, "WIN32_bios");
! }" t) F- y. v8 F  b    Memo1->Lines->Add("");
, |+ S5 x7 I; e) b$ f5 P. `" {}, {- M$ |$ \& u" K! c

! A8 c% R" {+ ?$ ~--------------------------------------------------------------------------------
' }8 c9 v, N& v) M( P; l, J
3 j/ u% o# m; R5 \# FWMI 可以访问的信息类型有:
" l, J6 W' p- B5 X* c   Win32_1394Controller
4 I' K5 y" U! a; W   Win32_BaseBoard
# {6 d, v5 |0 @. j  G" Y   Win32_Battery5 }* \3 E  I* M3 G: S( n$ W  w
  Win32_BIOS
- t  c: [, `2 F# j0 T   Win32_Bus3 C+ F5 z# W  Z% Y
  Win32_CacheMemory
8 q, v! a4 B  g7 W   Win32_CDROMDrive
$ D% D" V# A7 h9 X; g' k5 P* \   Win32_CurrentProbe4 }4 t/ S5 |8 a% o' H
  Win32_DesktopMonitor7 U9 y7 ~8 i5 k/ H+ v+ S  ?. w, _
  Win32_DeviceMemoryAddress
( i; \2 D! O& l   Win32_DiskDrive
  }5 C; T4 Y# n- v7 G& C   Win32_DisplayConfiguration
& Q5 w, R# I, C8 C2 }5 B+ X/ b   Win32_DisplayControllerConfiguration  |: |& R0 b) u3 d) k, V( I& f
  Win32_DMAChannel
8 Z0 E3 u1 |! }6 ~- h4 ?   Win32_Fan  Z/ M4 s  L* |* P3 L; E
  Win32_FloppyController2 N& o+ Y. p+ ]; @, w4 k
  Win32_FloppyDrive' p# m+ t0 S& v$ ~1 S) `+ z
  Win32_HeatPipe
+ ^' A9 `) C3 m$ f6 X0 a. \  R% _8 b   Win32_IDEController( `% {  x4 ]* N, C0 |7 W
  Win32_InfraredDevice% j6 h' j" D7 o9 ~" O, U0 \
  Win32_IRQResource
7 r6 ?. T( F8 {" C) R* l. w# n   Win32_Keyboard
) O- b6 [# a$ t8 `   Win32_MemoryArray
" k1 b) V; l# j+ c7 p) g) L2 \   Win32_MemoryDevice) t( e% Y0 K2 ~7 `' n% }8 x
  Win32_MotherboardDevice
0 s+ a& n% q* p. s  E   Win32_NetworkAdapter9 b6 O2 a& Y( ~, H( b+ [' J6 _
  Win32_NetworkAdapterConfiguration( A+ D- @# M) ]2 `& I
  Win32_OnBoardDevice6 j6 d* }' S) ^8 [! ]% B0 i
  Win32_ParallelPort/ l/ Z; D% `5 N% X
  Win32_PCMCIAController
6 a* v+ J' X6 ^: v. |' I   Win32_PhysicalMemory( o; p. @( W7 N4 E' z: \5 l
  Win32_PhysicalMemoryArray
3 f2 N. I: v- P# {4 ]+ C   Win32_PnPEntity, }  B6 n9 z7 ?9 x
  Win32_PointingDevice
* O; D* \+ [5 @! T3 K# ^1 M* J8 M! O   Win32_PortableBattery: J2 k. f0 z9 c* Q
  Win32_PortConnector
  @0 P7 G( e" C3 P) j! Z   Win32_PortResource0 O% ]4 P" ?# m- t
  Win32_POTSModem
9 J5 v0 J0 B0 w* y6 V' u4 I* U   Win32_PowerManagementEvent
4 H4 I( P% [; o   Win32_Printer% z0 t6 c! x0 o0 x/ w+ K
  Win32_PrinterConfiguration
6 T2 I8 T( V* z   Win32_PrintJob3 {5 P0 w( t7 D$ [$ Z3 B
  Win32_Processor
% S, d/ s* q* b& ]2 y+ V   Win32_Refrigeration
- o, J, n3 W" O. n2 ~4 I4 d   Win32_SerialPort
: k. w( W7 c; Q5 c0 G0 I   Win32_SerialPortConfiguration
6 @2 i, I3 G- b. ~   Win32_SMBIOSMemory; u( E& L  z$ n" r3 j6 q
  Win32_SoundDevice
$ Y3 n3 K. g7 k# u+ ?% f   Win32_SystemEnclosure! n8 y; Q. p, q5 |2 @
  Win32_SystemMemoryResource
3 K9 R5 J' x: y  z   Win32_SystemSlot
- m8 c* h" l# N4 F" n   Win32_TapeDrive! @7 Z$ r3 V# D" S
  Win32_TemperatureProbe/ T. O  ]! g  w% [# \  ?* H
  Win32_UninterruptiblePowerSupply
) i# j% L' l9 s  }( \, B% G   Win32_USBController: o, F4 b; W" ?+ F
  Win32_VideoConfiguration
9 _5 F$ O  [/ I5 W   Win32_VideoController
  J& w$ a; K8 x0 M1 r7 [   Win32_VoltageProbe
0 v) B9 o( Y: S4 \& Y* {
# D/ @: ]% A$ ?9 \; n. _以上类型(字符串值)通过前面写的函数 GetWmiInfo 可以得到相应的信息, 例如 GetWmiInfo(Memo1->Lines, "WIN32_bios");
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-2-6 18:58 , Processed in 0.017250 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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