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

[收藏]关于用WMI获取系统信息——编程实现

[复制链接]
发表于 2006-4-16 18:40:38 | 显示全部楼层 |阅读模式
    一直以来都没有用过WMI, 都是用的PDH来获取系统信息.感觉两者很些相似,都是类似于性能数据库,基本的一些什么硬件软件信息都可以比较全面的获得.只是用VC来调用相对比较繁杂,用VB和C#就方便多了.这些天到MSDN上找了些资料,总算大致搞清了一些编程思路.对于那些很想知道怎么获取诸如CPUID,硬盘ID,BIOS信息以及主板信息的人来说应该有些帮助吧.试着用MSDN的例子乱写了一通,以下是通过WMI获取BIOS的例子,不对之处还请指正 ^_^: # I" V6 u( s& T0 S( d+ r
  --------------------------------------------------------------------------------
( r( z: U( ]* `% k& Q  #define _WIN32_DCOM
* T$ ~: I* B" F! U$ u  #include <iostream> ) N* @5 \+ R$ g4 x
  using namespace std ; 8 r' T8 N4 U9 w6 L
  #include <windows.h> 2 R) p( s7 y7 v1 ^& a7 D
  #include <comdef.h> 9 O& B6 C2 k5 R( r) o
  #include <wbemcli.h>
" {( b6 K% H2 \  X& I" G' g; P1 D  
6 P' D  H/ ]/ W3 W4 r  #pragma comment(lib, "Wbemuuid") ( _7 N7 m' y+ u4 X, w' N
  
8 P/ r1 O" z5 y6 F+ `5 Y  _  int main(int argc,char**argv)
6 X  Z: @$ }# `  {
) {# U1 I; ?. U# I  HRESULT hres ; 4 K) I5 c1 h3 O7 S# |
  
% [/ a3 N0 z9 N* Y2 h  // Initialize COM.
# E1 y6 k' Q8 g- T: z* p+ O  hres=CoInitializeEx(0,COINIT_MULTITHREADED); ! t4 o9 q( d6 h" @- ~
  if(FAILED(hres)) / ?7 B/ {" A) [0 ^
  { 3 p# Z* m) S0 W! l1 [  T4 P; C& w( W" K
  cout<<"Failed to initialize COM library. Error code = 0x" , Y1 F# I# w# O0 S+ c, F9 I/ ?
  <<hex<<hres<<endl ; 1 \8 }' c2 C/ \3 |$ ]
  return 1 ; - L* z7 ^) [: K. I5 Q: }8 _
  // Program has failed. 3 v/ A2 b, I! U, p  G" u7 m
  } ' h  j. H  p5 ~. F" b3 v1 S
  8 Q8 q- h, |6 |$ p: K$ A
  // Initialize 5 p* R! U3 x0 O# U2 M: ]# S. E0 B( S! C
  hres=CoInitializeSecurity( ' n6 w0 w: _6 r- n/ p
  NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_DEFAULT,
( V. K7 h2 k* z2 h0 o# a  RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE,NULL); ! X% L4 u0 i; K9 M5 x" w
  5 y1 d. ~/ J1 N& }$ j6 m
  
! r2 L( c/ w2 M6 f  if(FAILED(hres)) 1 G) _9 D( D7 o' ]7 U+ }( n1 m
  {
# |( O9 Q1 `! L( i: V% m  cout<<"Failed to initialize security. Error code = 0x"
* _0 O" ^" W+ |+ b) a- O: N  <<hex<<hres<<endl ; % R! F2 V' Y" I5 q6 {- `( S
  CoUninitialize();
- _8 O( g8 v/ J* A  return 1 ;
- y$ _0 q3 y+ K) G  // Program has failed. 3 |+ Q+ \8 p" o1 k8 o, u2 d) E( u  {. s9 q
  }
/ e  I( U) H! ~* d& t  
: X' g- o! M% F8 \: ?  // Obtain the initial locator to Windows Management on a particular host computer. " {" {5 H& i% P8 k& R- k: U9 i( ]
  IWbemLocator*pLoc=0 ; 7 V9 c# O: h2 j
  
; }8 m" @! [& l6 Y9 r+ ?  J  hres=CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER,
$ A$ z0 n5 m+ S  IID_IWbemLocator,(LPVOID*)&pLoc); 7 B; E: Y( q$ Q% C) @
  ( d" A5 S( A. q; Q: t$ U
  if(FAILED(hres)) 3 T+ i) M  W- g
  {
* i( d7 z( q( l2 G! i  cout<<"Failed to create IWbemLocator object. Err code = 0x"
8 O7 v# h3 R9 z/ Y0 \" D9 Z  <<hex<<hres<<endl ;
- J, m; |( b; O2 M# |  CoUninitialize(); 9 [0 g5 T, w$ B* W7 o% Q
  return 1 ;
$ y0 ~& X+ t- Z# t5 C  // Program has failed.
6 w2 W( Y/ w( T/ P: B( M2 k: c  }
! C" n# M- }2 O! l" n0 T" ~1 R  : Q' c5 H4 ~0 a% N
  IWbemServices*pSvc=0 ;
0 ^; P+ K+ _  x; B  
* Q( `: O0 {( s! d0 F* l  // Connect to the rootcimv2 namespace with the current user and obtain pointer pSvc 9 z( ]4 {7 L6 M. V0 S0 P- ]
  // to make IWbemServices calls.   X" i% z9 m3 R2 m, R
  
; u* O1 [: J/ |. D5 ]  hres=pLoc->ConnectServer(_bstr_t(L"ROOT\CIMV2"), 3 I9 B: i0 k& {$ \6 Q! l( e5 E3 A
  NULL,NULL,0,NULL,0,0,&pSvc);
9 t* _" Z. b' v  p  2 u* `, |* T! c+ M3 P5 [9 C
  if(FAILED(hres)) 6 Y$ V  d- Z# {! D# C- L' C
  {
' X( o2 ?5 s7 B, T1 I$ q) Y  cout<<"Could not connect. Error code = 0x"
  Z9 ^. U8 n; q6 E6 `  <<hex<<hres<<endl ; 0 D2 [+ o* {" M/ l( z
  pLoc->Release(); : w0 J7 s: d5 x  ~5 E
  CoUninitialize();
9 L' L, s) _# X7 S/ p/ E  return 1 ; 4 P  L3 p- N0 t3 W" C. r( W
  // Program has failed.   a2 M( f+ N% g2 W% U+ G. {6 D* T
  } - k; Z" f" |# F4 Q! d/ i
  
3 ?  [: x2 G/ e* S5 A6 l$ {  cout<<"Connected to WMI"<<endl ; * C5 K3 u% u3 o+ f% a$ T8 b/ a8 f
  
* {. E) v4 @- w  // Set the IWbemServices proxy so that impersonation of the user (client) occurs.
0 ?  P0 y# M5 j: ~5 a  Q1 @9 J  hres=CoSetProxyBlanket(pSvc,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,NULL, 3 R$ F7 i! V' R- v, m8 \/ l
  RPC_C_AUTHN_LEVEL_CALL,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE); 7 q- i  Q- Z0 ~
  3 ^4 I  Y9 `1 H) g% v: Q
  if(FAILED(hres)) $ b9 k  W) M& I
  {
( q9 O9 d5 C4 i8 F8 r/ r  cout<<"Could not set proxy blanket. Error code = 0x"
! c0 h, H4 R( R" c* F  <<hex<<hres<<endl ;
, M$ n- `* \" l+ a6 p* ]$ s  pSvc->Release();
! ]( y0 {4 t. s0 y7 k% ^( g" S  pLoc->Release(); : i2 R3 G; R; t8 x: z2 X
  CoUninitialize();
- Y4 e2 u6 w! o% h  return 1 ; , R, q: ~( F, H
  // Program has failed. $ i( o2 q9 J5 k0 l& }8 `- W( }
  } ) @9 `, \" e9 d$ C& e% r7 ~- C
  
& [6 O# W* A0 O  
0 }3 F- O% c5 u9 o6 Z. H  // Use the IWbemServices pointer to make requests of WMI. , g4 W2 R* X) [1 x# j
  // Make requests here:
/ Q3 V& Q1 \6 x& a  
9 o: c7 f9 j4 s* y' X/ J; t  // For example, query for print queues that have more than 10 jobs + J! L+ D. @/ l+ n4 _. C0 z
  IEnumWbemClassObject*pEnumerator=NULL ; 7 k1 c0 W# u9 M' B% R  e
  hres=pSvc->ExecQuery(
0 X, V5 X; p  ?% P  bstr_t("WQL"),
& i+ T4 R# F; m9 v  bstr_t("SELECT * from Win32_BIOS"), 9 ~" c- B1 \% g
  WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,
' Q% b1 w$ y0 t9 p9 E  NULL,
( J) a3 ~3 T& a  &pEnumerator); ! c% b2 d# @/ k4 ?. N+ _; }
  
+ Y- e$ v. i" f8 K6 K; t7 h  if(FAILED(hres)) 1 b8 d. w$ Q6 u4 I4 R
  {
9 k* L# U) N; F  cout<<"Query for print queues failed. Error code = 0x" . _2 o' L8 H. e
  <<hex<<hres<<endl ;
9 s! l; W8 |7 D+ W- Y# ?& G  pSvc->Release();
3 D' S6 e5 f7 G3 S# A  pLoc->Release();
; M3 f" ~' B7 e4 w& i  CoUninitialize(); 0 }8 a6 y5 V5 ]5 b) e7 T9 @! G
  return 1 ; 1 }6 y5 z: c6 [5 S
  // Program has failed.
& S: }0 r8 L: b% K" H! U  }
( S: T0 I6 ?3 D0 S% l% C3 T) G  else
/ ^( E7 d6 L' ]! \' f  { & ]* L& V" W8 ?5 q- D
  IWbemClassObject*pInstance=NULL ; , q+ H( a  F7 Z0 S9 \  x0 d! Y
  ULONG dwCount ; ) E2 d: I  ]+ G- K: X3 O
  while(pEnumerator->Next( % K0 E  ]8 R, @6 L) o& ?5 x6 B
  WBEM_INFINITE,
3 u8 F! M& X9 A; U0 e3 W  1,
' Q) J; g- a/ Z+ @6 I  &pInstance, $ h1 G) o* _5 g. i- ]0 f. Y
  &dwCount)==S_OK) * o/ _! C  v6 A8 q
  {
" l" Z7 D# V8 T2 B! g/ s% a  SAFEARRAY*pvNames=NULL ; $ F' V& w8 d% ]# q/ B1 X
  if(pInstance->GetNames(NULL,WBEM_FLAG_ALWAYS|WBEM_MASK_CONDITION_ORIGIN,NULL,&pvNames)==S_OK)
$ K" {3 R7 q) i0 E5 i, k  { 5 s. N/ n: f# t
  long vbl,vbu ; 6 {+ S, i& \, a" V4 c3 `
  SafeArrayGetLBound(pvNames,1,&vbl); " f( f0 C# A+ L1 ~! j& C
  SafeArrayGetUBound(pvNames,1,&vbu);
  w! ?0 J6 P5 |0 X9 Z! v  for(long idx=vbl;idx<=vbu;idx++)
5 d  u4 `, A$ e- {0 n  { - j$ }# w  f) D) D
  long aidx=idx ; ( \! E. v* E" {# c; ^% v/ C* E
  wchar_t *wsName=0 ; 5 M! l$ I! ^* v9 I+ j, f3 m3 n' ?
  VARIANT vValue ; ; A& a, q3 E8 @9 D! y
  VariantInit(&vValue);
6 S. c1 \9 U3 r  * A  P2 Q, R: E/ s( z
  SafeArrayGetElement(pvNames,&aidx,&wsName); 3 t6 {- U. y1 {* \/ K) D3 L
  
8 f4 z8 T6 q4 B: w8 `9 r+ q! I  BSTR bs=SysAllocString(wsName); 6 D3 ]2 Z3 L+ N' {' A
  hres=pInstance->Get(bs,0,&vValue,NULL,0); ) r/ ~; w4 P5 E7 m
  SysFreeString(bs);
- D% B& e. h% p1 ?9 J  
. r4 F% U, h, ]  7 s5 v1 @! P2 J; r4 z' Z6 C
  if(SUCCEEDED(hres))
7 T( o, f2 Y5 U6 c  { : r/ [5 I8 ~  H) Q% A
  char szANSIString[MAX_PATH];
2 Q3 j6 _, j% T) I7 H+ S" }# c  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,wsName,-1, % I' b$ V. p  i  a+ X
  szANSIString,sizeof(szANSIString),NULL,NULL);
! B  s9 C- U8 _8 R3 r3 O  
2 E* B  f. B" i) p$ S  cout<<szANSIString<<" : " ;
8 P* v- d! r- ~1 {5 s  switch(vValue.vt) , Q% O4 z5 D8 C& x
  { 8 P% J+ E) z& q9 `4 Y
  case VT_BSTR : 1 Y5 C( n9 M9 ~5 C0 O8 N- B
  wprintf(L"%s",V_BSTR(&vValue));   A- b; n9 S) |+ E
  break ;
( e; w! T- p1 d; N! h  case VT_I2 :
+ Q% U3 x) F* z9 `: w  wprintf(L"%d",V_I2(&vValue)); 9 w5 `2 H. v1 B9 A, z! n) x
  break ;
+ o- g* d% Q( i2 h  case VT_I4 :
1 Y# |, p" z; N  wprintf(L"%d",V_I4(&vValue)); 7 W2 T  U8 N9 X4 F, M( n
  break ; ; _2 g) u  d; a
  case VT_BOOL : 6 ~1 Z  r% C' {1 }
  wprintf(L"%s",V_BOOL(&vValue)?L"TRUE""FALSE");
8 z& }3 I& o& T+ ~2 P! ~3 C  break ;
, m" `$ o% R2 Y; Q) i  default:
# \' M" i% i$ L  /*WCHAR tmp[100]; % y* m# {( b& L& V! A4 i& W& d
  wcscpy(tmp, V_BSTR(&vValue));
- @# e2 E% w) g: M8 ^  char tmp1[MAX_PATH];
! h8 q; h3 z9 g9 `  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,tmp,-1, 3 U& o3 c! J6 f. C; _" @
  tmp1,sizeof(tmp1),NULL,NULL); ' I/ e$ A$ I; F
  
8 b; a/ ]. C3 L% `* A9 F9 i8 i& V  cout<<tmp1;*/ $ o2 Q" q1 T3 |' n% f7 \* e
  break; : P* z1 @+ t" \# a( {5 n
  } 5 Z/ o. g  G8 E0 S, R# u6 V
  cout<<endl ; 5 _# R; \( a# C( w
  } 9 m$ e% @" y* m& `2 h, [
  
4 ~- t" d) Q$ ^% r& x: l5 s! C  SysFreeString(wsName); ' y4 ?- h* M5 z
  }
+ H# Q1 c; O- i3 N# G4 M2 M1 l9 }  
/ I0 R! B: X4 r1 d' Y  } 5 b- b$ n) ?9 g6 n2 f9 ?1 U  u
  else 9 W" b3 J7 m0 {5 r
  {
3 ~5 \; `5 D" R  cout<<"Query for print queues failed. Error code = 0x"
9 [* P! X4 ^  {+ }% }0 ~  <<hex<<hres<<endl ; ! r; N, B4 z8 \( e
  pSvc->Release();
$ ~! n$ L9 U3 Y  pLoc->Release();
$ ]  P3 O8 x  S* [/ W2 n* p& s" u  CoUninitialize();
' Z; s: H0 w  \2 [* X- Q9 h  return 1 ;
; D$ K( s! m# Y& F) n  // Program has failed.
5 N/ F* t( N- D& M9 [' h4 t4 I9 R* x  } 1 @; Y* f6 T. F: ~5 @* C
  if(pvNames)SafeArrayDestroy(pvNames);
: D, g" }4 u" a" n  [3 P- ?( v  \4 Z  }
5 h2 _' O, m$ X% z) f) s  z+ U7 e5 N  if(pInstance)pInstance->Release();
. N% x$ _$ R0 J1 _  / V& n5 z0 w+ E7 g: z
  }
$ k2 u- A  J% Y2 N5 a  // Cleanup
. \; M' r2 K6 {" W  // ========
! P, [/ S. K* \/ V  _% y  pEnumerator->Release();
: [% X- G' _3 ~3 W, j# V  pSvc->Release(); * }7 ^3 X/ e. H# k
  pLoc->Release();
: {+ l: g! S2 Y* g. N! j3 ^2 W: j  CoUninitialize();
0 a. _+ A! `$ q  * U5 b' A  F$ L7 s
  return 0;
! Y& |# K/ K, J0 e' ~9 r6 f# t3 h7 \  // Program successfully completed. 8 }& A- \$ y! a
  } 5 ?5 r% K* C6 B0 r
  //-----------------------------------% L, M8 X8 t) [$ H- D8 m- M0 L
  
: x7 S# @3 T' d! K% ]  G$ S  对于怎么用BCB编, 感觉还容易一点,因为我在类型转换的时候碰到了一些问题,而在BCB中的Variant类做了比较好的封装, 具体代码可以 http://www.cppfans.com上找到.
; a" g7 P" r! i) q8 c3 [5 Y  
8 Q" D8 d: ^% ^  void GetWmiInfo(TStrings *lpList, WideString wsClass)
4 C9 l% c0 d+ y  J2 E8 `  { $ p* Q( P6 m$ Z* Z1 K0 t
  IWbemLocator *pWbemLocator = NULL;
$ |! s4 A/ N! r  V/ b$ m9 c, t  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)
4 X7 q5 M4 L+ f6 c  {
7 F# J0 h, R% `: C# ]  IWbemServices *pWbemServices = NULL;
9 }( V: y. @0 V: [. s; _  WideString wsNamespace = (L"root\cimv2");
' }, J( R& X5 Q$ n3 \  Q( y  if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)
. M% d! S. b" J# |  {
9 T9 m; B) U# Q2 K+ \' I* v  IEnumWbemClassObject *pEnumClassObject = NULL; 2 A) o4 p0 G; }
  WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass; 3 X) z$ O- M, F9 n$ f3 T" y
  if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)
5 m: T7 ?2 G. p8 _6 V* X0 C& {  { ; w! U" Q0 a8 U7 L& w/ f' x
  IWbemClassObject *pClassObject = NULL; , Q4 h1 w4 v5 B; H) K
  ULONG uCount = 1, uReturned; 3 F* S  d5 s+ }
  if(pEnumClassObject->Reset() == S_OK)
# L2 A+ l. M/ s, s" n" d+ I  { " w1 H6 V! ?- b5 y! y
  int iEnumIdx = 0;
: {1 r: {7 p! K: l3 }, `  while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK) 2 ]! o) b' `( r$ B; A
  { ( ~" A! B& n  M, a
  lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");
0 O5 ^$ q/ E9 r9 J5 \$ B0 U  % J8 Z/ t$ ~$ d  K/ d
  SAFEARRAY *pvNames = NULL;
; R+ _6 |4 W! U- N  t4 F0 U  if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK) 8 C3 V  P" v' x: C% s% R4 v. K
  {
- I- q% n8 T! d" U- ~; w! H$ o  long vbl, vbu; ) t0 @' S' L5 F
  SafeArrayGetLBound(pvNames, 1, &vbl);
& b& e9 v  A$ f* G2 Z0 T- D9 U  SafeArrayGetUBound(pvNames, 1, &vbu);
4 y( I6 P  H9 B  for(long idx=vbl; idx<=vbu; idx++) ) s8 N; U4 o$ ]9 z/ E/ ^1 G
  {
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-6-19 08:45 , Processed in 0.014711 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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