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

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

[复制链接]
发表于 2006-4-16 18:40:38 | 显示全部楼层 |阅读模式
    一直以来都没有用过WMI, 都是用的PDH来获取系统信息.感觉两者很些相似,都是类似于性能数据库,基本的一些什么硬件软件信息都可以比较全面的获得.只是用VC来调用相对比较繁杂,用VB和C#就方便多了.这些天到MSDN上找了些资料,总算大致搞清了一些编程思路.对于那些很想知道怎么获取诸如CPUID,硬盘ID,BIOS信息以及主板信息的人来说应该有些帮助吧.试着用MSDN的例子乱写了一通,以下是通过WMI获取BIOS的例子,不对之处还请指正 ^_^: ; A* |: N& _! E" C
  --------------------------------------------------------------------------------
$ Y/ F0 F) J/ B$ L: k& m3 H& i9 _  #define _WIN32_DCOM
; a& ^& q8 y* D6 z, B/ s6 U- V+ q! q  #include <iostream> , a( X, E( v& ~" l' g1 T0 R; J" ]
  using namespace std ;
! S* }" r1 ^& M+ `2 B  #include <windows.h>
$ s4 ]9 r6 a  a0 @. K6 \/ z1 @9 `  #include <comdef.h> 5 u% c! Q5 g/ s# X. W
  #include <wbemcli.h>
/ u# ^- N( n% m# k1 [  8 ]" W5 t# [0 g6 d( R
  #pragma comment(lib, "Wbemuuid") : W+ H* i9 a' s) W  z- g6 @+ J
  
* S8 O' \8 q, z5 }; w* \9 j# {  int main(int argc,char**argv) " k# i$ D! k  {
  { % L1 K5 i" V3 Y8 w# {$ o# q. Q6 |
  HRESULT hres ;
! k1 V/ }  [$ i  
# P; P; ?9 m9 [  // Initialize COM.
1 K% ^! v" A3 J" E  hres=CoInitializeEx(0,COINIT_MULTITHREADED); % w; H& G" \# O4 z
  if(FAILED(hres)) - g5 ?1 q+ c  r8 @8 f* k
  {
, R0 B! A* i9 h! v. U  cout<<"Failed to initialize COM library. Error code = 0x"
8 _# b2 y; Y3 B4 _7 Q  <<hex<<hres<<endl ; " e) G( c0 Q; s2 l
  return 1 ;
5 C" c  H: }/ |  // Program has failed. & d3 J: a# J0 l; Y, G" t/ T( j
  } ' g/ e$ ]6 J( @4 Z8 n) F
  
* a& ^! y  G! m" H6 W/ X  // Initialize 4 k3 n% C- m6 ?' g1 m0 v" D) ]4 G
  hres=CoInitializeSecurity(
0 t8 t" \; r. d7 V  NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_DEFAULT, 2 s0 U% f! u1 v( w- t3 D: U
  RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE,NULL);
0 }9 e- l0 o( e( h  
+ O3 {+ {7 p" @* ^0 K8 k  : \8 r0 Q- \$ L' c2 }
  if(FAILED(hres)) / ]4 z* d" Z) [5 f
  { % j4 P( [: z/ l+ i
  cout<<"Failed to initialize security. Error code = 0x" 7 q7 b( F* |& ^' L/ a5 q. f, G
  <<hex<<hres<<endl ; 3 |+ f& P# {* v- K
  CoUninitialize(); $ x& V! n% F+ b. h+ L
  return 1 ;
9 t9 I" r& q5 L7 x' W/ w1 @8 n  // Program has failed.
) l8 d; u8 [: P% u6 K" u5 a  }
3 ~$ K+ b# N8 U4 m1 ], H, s5 A  
8 W9 H/ l9 x# s; M  // Obtain the initial locator to Windows Management on a particular host computer.
8 S8 l8 W% K# S+ D" t  IWbemLocator*pLoc=0 ;
/ L! m8 {- _  ?7 j  * N- V5 `6 l  L6 t
  hres=CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER,
/ w* F" d! c) P: K. f: U3 M  IID_IWbemLocator,(LPVOID*)&pLoc);
5 _; t4 k: d3 M6 R  , ?/ _( C% C) G5 l+ Q5 q1 @
  if(FAILED(hres))
2 ~  y$ X! P/ F4 }5 }( M2 Z! H( P  {
2 _" r1 P. S7 ~) I* F' K5 n6 j1 P  cout<<"Failed to create IWbemLocator object. Err code = 0x" ( Q. m4 h7 f& U  ]8 m7 U+ _1 \' G0 z5 V  q
  <<hex<<hres<<endl ; # V- b$ `# ~/ V" m
  CoUninitialize();
! ]5 d# m; w. J; S3 C  return 1 ; ( r2 _, d6 B1 U9 R
  // Program has failed.
7 U& G4 J0 ~$ f2 C% p: g' d( U: b  } 7 n% ~9 l1 i' }) S, S
  $ {  z  p7 [# w: p5 a
  IWbemServices*pSvc=0 ; $ G' ]8 f- r/ Y7 r+ y( J" {
  # T5 m) x. J9 M  K
  // Connect to the rootcimv2 namespace with the current user and obtain pointer pSvc
  R2 I' ?# @3 x! d* i. O+ u  // to make IWbemServices calls. 7 r; i/ D3 R# g) B0 u
  
# y+ f0 T! Y! C  hres=pLoc->ConnectServer(_bstr_t(L"ROOT\CIMV2"), ) ~0 _& Z7 r1 P8 S$ w
  NULL,NULL,0,NULL,0,0,&pSvc); - ~; Q! e3 l2 }0 i' z. J$ e
  / v" V2 a2 w9 r
  if(FAILED(hres)) ) d0 C/ S2 E! y1 m& Q& a+ `
  { 5 _2 Q2 Q! y( N: h" `
  cout<<"Could not connect. Error code = 0x" 3 ^6 J$ ?6 y  O% l% m" O2 x
  <<hex<<hres<<endl ;
: \9 P0 v. R* ~- P3 D* Q  pLoc->Release();
" ]3 ^: m' J9 I( Q3 U$ [! d2 S  CoUninitialize(); 3 p+ q- x3 H0 ]) w$ w7 r  P
  return 1 ;
' Q' M& c  B% g! t" @" v: `% c  // Program has failed.
! S0 \% i! V% N- N( I  } : }5 k+ t. t, ~$ V. t! `( U) k+ @
  + K5 z" G6 w1 N$ ?- W& e
  cout<<"Connected to WMI"<<endl ;
. U' F' I$ F1 z/ M& w/ h; R  0 [- }5 P) t* }( K% K
  // Set the IWbemServices proxy so that impersonation of the user (client) occurs.
6 u5 G. o. L* f1 H9 P1 D  hres=CoSetProxyBlanket(pSvc,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,NULL, ( }& k1 w+ ~. c" S1 x% t
  RPC_C_AUTHN_LEVEL_CALL,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE);
+ C- R; s' r3 |8 |  : w( _" u! M* y' E7 ?5 r
  if(FAILED(hres)) 9 x7 s& i3 _2 e9 L1 r
  {
6 S" B# x. Q5 q1 `- K  cout<<"Could not set proxy blanket. Error code = 0x" & g+ h, b# E4 Q3 C3 v0 f/ q
  <<hex<<hres<<endl ; & L& {$ N. _! t5 ~: S; Y4 E
  pSvc->Release(); 9 v+ Y4 p; |- B4 U) _
  pLoc->Release(); ! |5 ]! ~0 w, b5 X  P$ n# V3 G3 x' ~( r
  CoUninitialize();
& T4 P1 C* o/ n( C! @9 U" K6 `  return 1 ;
- E0 U% P0 I( J9 y5 F  // Program has failed. ) Q3 S# I; v) k3 z3 \6 I
  } ' B! c; H4 W. e9 n" k
  ; k! V# @$ x! n" A2 @1 j
  . E# P# y/ W$ @  v! q
  // Use the IWbemServices pointer to make requests of WMI. ' ?5 Z) h/ X- o( y7 v$ {
  // Make requests here:
( r$ {4 n) T8 @4 G$ ], ^  
. ]6 J# m; l5 H- T! D  // For example, query for print queues that have more than 10 jobs 5 @2 ^: A  H# O/ z
  IEnumWbemClassObject*pEnumerator=NULL ;
# t* D) F2 `/ N  e$ M  hres=pSvc->ExecQuery(
6 |& U1 @4 }1 i. r6 x  bstr_t("WQL"), 7 s: m! U+ U# }; Q! q! n% L
  bstr_t("SELECT * from Win32_BIOS"),
- X8 a% C9 \& G+ D  WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,
  ~! v5 X5 X) s5 h  P  NULL,
! c( g# e( v! m9 E7 Q  &pEnumerator); ' M: F* w, [. F7 _+ O. [( S
  . k2 ?3 D$ H- W6 O
  if(FAILED(hres))
3 M& C$ w8 G2 C$ Y$ _! k' E# ~; }  {
/ P& [# t  ]& q9 K  y2 t  _' }* l, F  cout<<"Query for print queues failed. Error code = 0x"
8 z; }% i: C3 Q0 w3 c  <<hex<<hres<<endl ;
4 {: ^. v$ b. G3 ~  pSvc->Release();
* R$ Y& W  R! K  pLoc->Release();
1 Y  P, {/ e. p/ H  CoUninitialize(); 5 v: G# m3 y+ C! f+ _
  return 1 ; 8 t8 z' y/ A  X, a' A  ~2 @
  // Program has failed.
3 f: ~+ h1 w1 K" [/ V/ v6 S  }
$ ]3 Q2 G; H# D) w2 w0 h  else 0 ^1 A3 p% O8 x, d8 g
  { ( N* |! C0 a% J7 B
  IWbemClassObject*pInstance=NULL ;
6 L, A1 s, X0 K! X$ g. H  ULONG dwCount ;   }& R5 O0 k* S4 j% T
  while(pEnumerator->Next( & E" D% l2 T! ^: [
  WBEM_INFINITE, 2 F: W* y/ _; ]4 [7 P
  1,
8 [$ Q( C% B) V+ Z: U  &pInstance, ) V* T9 I1 i% z$ D/ t( B
  &dwCount)==S_OK)
) z: [+ S- Z6 K6 y& f5 X/ P  {
5 K5 |$ x" U! D- g4 f9 `6 |  SAFEARRAY*pvNames=NULL ;
( y( z" q& G5 n  B  if(pInstance->GetNames(NULL,WBEM_FLAG_ALWAYS|WBEM_MASK_CONDITION_ORIGIN,NULL,&pvNames)==S_OK)   x, y$ A' [4 w* j+ o' I2 o/ k
  { - ^6 [0 Q3 b* c" P% P
  long vbl,vbu ; 4 ]9 R/ |4 ~6 {/ M
  SafeArrayGetLBound(pvNames,1,&vbl); 5 M$ H8 t% U; A
  SafeArrayGetUBound(pvNames,1,&vbu);
+ D! U7 `" O# d3 p7 I  for(long idx=vbl;idx<=vbu;idx++) 7 m' B  {9 b) w% W- W8 [2 S
  { 1 I2 J* N' r$ {' ~5 F; U; o
  long aidx=idx ;
0 ]8 W& S; t. [* I( r  wchar_t *wsName=0 ; 7 \' P. ]$ S, D) e1 M/ f6 l
  VARIANT vValue ;
1 O) F% x( T' x- _  VariantInit(&vValue); 8 L* |' m2 V8 H* P
  4 h7 S+ n2 j" E& L
  SafeArrayGetElement(pvNames,&aidx,&wsName); 4 d' U0 v% J& v. D  W0 j
  * v6 }: s$ s( ?/ G( i8 X" j
  BSTR bs=SysAllocString(wsName);
" j3 o' h$ P% ~3 y  hres=pInstance->Get(bs,0,&vValue,NULL,0);
' {, p& i; ~* g5 @  B9 E  SysFreeString(bs); 9 K0 [  t! }4 u: _
  
. D( e% q; e+ R    R# g9 Y. v$ q0 C. n
  if(SUCCEEDED(hres))
5 ^) `. h; `* e  { ' e$ Y8 p2 M6 I& _) f
  char szANSIString[MAX_PATH];
9 P$ V. U" f9 _" T% L8 b% s1 B5 E  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,wsName,-1, ( }9 L- Z+ I% J9 u( W
  szANSIString,sizeof(szANSIString),NULL,NULL);
" m0 I. `0 D, ~9 U/ t1 |  5 E! G) o6 D; b+ q
  cout<<szANSIString<<" : " ; 6 _4 ~2 Q" n" T+ l8 |! b/ z
  switch(vValue.vt)
: Z6 E+ u# U; ]+ X3 {  {
+ L+ L1 J5 K/ \. a( F; Y4 X5 s  case VT_BSTR :
7 |' J7 d& ^* o3 v7 J5 d& w/ r  wprintf(L"%s",V_BSTR(&vValue));
+ i: Q2 j& E& K, ~9 D* t  break ; 2 Z4 }; r4 Q5 u6 l
  case VT_I2 :
/ S& v3 U; e  ?1 e. R% i  wprintf(L"%d",V_I2(&vValue)); 8 t6 C  X( v* O! f1 X
  break ;
7 H( {0 h& j' U+ o1 v; F, l( o) ^  case VT_I4 :
! f1 I( K3 f" @+ _% y  wprintf(L"%d",V_I4(&vValue));
& b4 }1 e1 h, A( v  break ; . d& k  w, C; J, F7 t  @; U9 A, B
  case VT_BOOL : 8 Y9 E0 n# S, p6 \
  wprintf(L"%s",V_BOOL(&vValue)?L"TRUE""FALSE");
; {! O4 j! _" E6 n7 E  break ;
+ D- v; \" X3 R  default:
5 B% j. e  H1 I) K" }6 U  /*WCHAR tmp[100];
* n9 H: S4 [0 w, G" P  wcscpy(tmp, V_BSTR(&vValue));
  l% h( A) d7 m6 g6 \' E  char tmp1[MAX_PATH];
5 [! }/ o1 h5 ~+ ^/ {  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,tmp,-1, # m* K- [3 z+ Z$ s9 t8 c
  tmp1,sizeof(tmp1),NULL,NULL); / v' I. E, a# p( C% @3 B, C; t
  0 Z" V5 c& _8 X3 g4 K
  cout<<tmp1;*/ 2 c8 J8 ]: C+ q6 I
  break;
8 o5 D( p; z1 X. J6 \6 _" K  } ' m) E3 c: {1 }
  cout<<endl ;
8 ^$ c( E5 ~% F$ j1 ]  }
' C7 y0 ^$ ?$ n# W, \) y' h  ) t+ w1 z* Z( j
  SysFreeString(wsName); & h- }. w5 l* U/ N+ L( k1 \: W
  }
( I9 N- c( O0 U8 @1 @  4 q, ]/ B9 s: L! o
  } : z+ d4 w; Y* c' T- o- P
  else
8 {- X4 A$ u# e' d( G  { 9 t) A$ e. W1 N6 @% d# |$ k1 ?' s
  cout<<"Query for print queues failed. Error code = 0x"
9 P$ x" c. F6 X, }  <<hex<<hres<<endl ; 2 o2 Y# D- @' I8 ?# c& z6 E4 y, ?
  pSvc->Release(); 1 G! J$ B+ D  {  |
  pLoc->Release();
8 g) [% a- w0 I9 P- G* K% l  CoUninitialize(); 8 F& E" X; p! k4 A% a# G
  return 1 ; , S* y- R  y/ l3 b
  // Program has failed. ) A7 p) k; e7 d# w0 I3 |6 {; `
  }
; g1 H' W. m% J8 [  if(pvNames)SafeArrayDestroy(pvNames);
1 m. ]# H4 @7 d6 r! }* F+ _  } 3 v( j8 h  ?! e
  if(pInstance)pInstance->Release(); . y5 R9 a. v( d4 V/ \% N: F
  
& {4 u; K) \$ E  } ' {# n# Z9 ?, F. U  K9 I3 p
  // Cleanup ( T4 S/ G' ~8 z
  // ======== 4 }& y0 w+ S! P& k' C
  pEnumerator->Release(); ) W: ?9 _- B# A7 h. D$ m8 W
  pSvc->Release(); 4 ]( u- ]" j8 f
  pLoc->Release();
- j, J8 k6 ]. m; N! I8 r% L  CoUninitialize(); ) O7 D" r: @9 w0 {, a- G
  & h( Q+ Z/ V6 I
  return 0; : k% Y6 N+ T, ?( z5 P! d& c, n
  // Program successfully completed.
5 T+ p7 O" I6 J# z$ b. z6 [- I* T. F. X  }
$ i$ u+ `% m& x  //-----------------------------------
8 w/ g; l2 g9 h) y5 ^! U% z6 b/ Y  
) D0 b( X3 G/ [$ ]8 E8 q2 u  对于怎么用BCB编, 感觉还容易一点,因为我在类型转换的时候碰到了一些问题,而在BCB中的Variant类做了比较好的封装, 具体代码可以 http://www.cppfans.com上找到.
( n# k- l5 \; ^$ b# y( x  ( x* T0 q' E  ^) h/ T+ t
  void GetWmiInfo(TStrings *lpList, WideString wsClass) 2 d, S0 U9 r% U. W: I3 M
  { ( `1 O% Z/ ^" r- r# {+ W3 o
  IWbemLocator *pWbemLocator = NULL; 5 Q# m) d3 U8 N) O' C( b
  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)
/ j2 l7 w# ~( I2 l  { % R6 D$ [: @: G
  IWbemServices *pWbemServices = NULL;
( H. d( t1 I( }: i$ p/ W, c  WideString wsNamespace = (L"root\cimv2"); / y  G* q& @( d# ]- i
  if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK) / b( B1 L. ^0 p
  {
4 R( @! X/ ?  {+ F  IEnumWbemClassObject *pEnumClassObject = NULL;
3 ]5 R% z! d1 J# U% J" ]  WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;
* o, t, |+ O9 `  if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)
0 C: g8 C' L6 V9 d7 d  {
$ G2 \2 S/ V0 D  IWbemClassObject *pClassObject = NULL; 3 u2 c6 H- H5 Z$ i3 E* E/ U
  ULONG uCount = 1, uReturned;
" o0 {" T, z8 w# W  if(pEnumClassObject->Reset() == S_OK) 3 e. D( Z( m/ |; b! J" X3 r7 t
  {
2 b3 K4 m8 c: z; ^2 E$ M  int iEnumIdx = 0;
* n7 O( Y0 O5 l0 f  while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK) + ?" @) n. i4 Q1 o; N
  {
" A1 g* i2 R& x3 }' I2 b$ ^4 Y  lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------"); 0 w5 X. `6 ^- \) |4 E
  
1 p) F' d: G* R. {; x# I  SAFEARRAY *pvNames = NULL; 2 C4 W/ M1 U/ X
  if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK) 5 r; [% F. R4 V9 A$ K
  {
; e1 r0 O& J1 i3 r; ^  p  long vbl, vbu;
. X6 t( E) N% v' f# q# u  SafeArrayGetLBound(pvNames, 1, &vbl); # u5 p) _1 }. l/ S2 y
  SafeArrayGetUBound(pvNames, 1, &vbu); 6 r( A. T( H- u; H' L) B4 K
  for(long idx=vbl; idx<=vbu; idx++) / c" d  f  |& c
  {
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-11-14 20:12 , Processed in 0.016815 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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