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

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

[复制链接]
发表于 2006-4-16 18:40:38 | 显示全部楼层 |阅读模式
    一直以来都没有用过WMI, 都是用的PDH来获取系统信息.感觉两者很些相似,都是类似于性能数据库,基本的一些什么硬件软件信息都可以比较全面的获得.只是用VC来调用相对比较繁杂,用VB和C#就方便多了.这些天到MSDN上找了些资料,总算大致搞清了一些编程思路.对于那些很想知道怎么获取诸如CPUID,硬盘ID,BIOS信息以及主板信息的人来说应该有些帮助吧.试着用MSDN的例子乱写了一通,以下是通过WMI获取BIOS的例子,不对之处还请指正 ^_^: ( \' e3 w% z; L7 T+ @6 y4 e
  --------------------------------------------------------------------------------
6 [/ V, D) o$ v5 k/ Y( e) q  #define _WIN32_DCOM
+ V& ~) a* X. B1 O6 ^( m5 _" m  #include <iostream> # @5 V* p% \3 k/ v/ B3 j3 t
  using namespace std ;
* o$ h2 C2 R/ h: V* v% e+ H  #include <windows.h> 9 d/ [& ?* A+ e' E" \# }0 @* j
  #include <comdef.h>
6 N; w! e6 J) s5 `# z& P  #include <wbemcli.h> & T- ]! q' z. o: _# J. O5 g
  
3 X) j# S1 F& h! r( `' f- m  #pragma comment(lib, "Wbemuuid") # c1 G0 J) Z8 r% u& x( ]
  
) Z$ t9 H" @+ x. ]  int main(int argc,char**argv) , r+ ~( A; o6 ~
  {
2 h; }. ^8 d- ?4 Z% V  HRESULT hres ; 0 e/ V7 \! R( ]$ @
  
+ ~0 F7 z  P, i; }  // Initialize COM.
! n$ k& c; R9 L" X  hres=CoInitializeEx(0,COINIT_MULTITHREADED); # @9 x/ b& e  D! X3 q
  if(FAILED(hres)) - g8 a$ S, H! `# ^, q# [7 a# j
  {
/ A3 A0 e7 H1 ~9 O# K" Y& V5 q  cout<<"Failed to initialize COM library. Error code = 0x" # u4 U, F5 m& }. X6 x
  <<hex<<hres<<endl ;
" n9 A3 m/ z5 a/ M  return 1 ;
# b4 P0 \( ]9 y: ]. _- P  // Program has failed.
& n$ L# Q& S" S. f  } . N  T6 _: K& |' l0 c' Z+ B/ E9 E
  7 G& i* I# {$ s8 _6 B$ y& x
  // Initialize ( p7 S* B( K0 y
  hres=CoInitializeSecurity( 4 ?7 Y' r) J( m% D8 `6 C* x' }+ y! t- C
  NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_DEFAULT, 7 |$ K0 ^5 \) R5 k+ N" n5 K2 p
  RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE,NULL);
6 }# g# }% M! d: A3 H/ ~/ g* \  ! b7 i& c4 ~' E% F- n+ A
  
6 g- }8 S0 M) I/ r4 D' P5 C  if(FAILED(hres))
8 l. B7 h5 ]6 i9 U  {
# l# n1 n) T5 K0 `# s( t& n3 ~# b  cout<<"Failed to initialize security. Error code = 0x"
* i7 B; R' {. w: G9 n3 m  <<hex<<hres<<endl ;
4 L2 }( _% s' d, U* |  CoUninitialize(); 3 K4 x3 k$ ^1 ~- I' A" b
  return 1 ;
% W8 i- B: y& J0 f  // Program has failed.
- j; i% ]' J& q9 \! ]  } : Q. v, y+ G2 }" i
  
# j5 l" g3 R  A, r# q0 `  // Obtain the initial locator to Windows Management on a particular host computer.
3 C. r$ O' c0 L; y; e6 L  IWbemLocator*pLoc=0 ; # S# U$ Z- N. n( ~
  $ ^2 ^, R  o8 l4 Q; ]
  hres=CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER, 0 P' x' \4 Q* n/ B% A; W
  IID_IWbemLocator,(LPVOID*)&pLoc); 7 C0 |! l: T8 m! C# \1 \8 d
  
+ X+ j: n- w1 e0 K  if(FAILED(hres)) ! S% y' N; ]  a. A% p! E- H, }
  { 6 S! e  u$ y* x+ {
  cout<<"Failed to create IWbemLocator object. Err code = 0x"
, a8 N$ n. `1 N3 ?7 c  <<hex<<hres<<endl ; ! f! q0 d( h# ?
  CoUninitialize(); / I9 l* M  x9 A5 }7 m. z1 z$ _; n, K
  return 1 ;
) X; U+ W* Q/ N  B9 D% T& I& F7 J8 d  // Program has failed. ) x% o+ i+ p; c1 s+ E/ c" k2 D) x& j
  } ; U7 ~) l6 _+ ?5 @* N$ R
  $ I  D6 a! ^: i0 z- V
  IWbemServices*pSvc=0 ; $ `/ x9 T3 G: H) G
  2 N7 u! }4 ^$ _% ]) E0 z, M, i. o) x
  // Connect to the rootcimv2 namespace with the current user and obtain pointer pSvc
' I% g- p8 G$ V' A0 z' j' y3 }  // to make IWbemServices calls. 6 h- L; @* i6 W6 R
  + @( {  H3 q2 r$ h# x
  hres=pLoc->ConnectServer(_bstr_t(L"ROOT\CIMV2"),
% w; q& _7 l! F1 |  NULL,NULL,0,NULL,0,0,&pSvc);   C; C0 @/ x% x' Z
  
2 {, |" X0 y( U; x  if(FAILED(hres)) 9 _( C2 r5 Y/ _. H
  {
& m: K! d- s4 V2 x1 u; Q  cout<<"Could not connect. Error code = 0x"
3 U& o3 r# B# D/ \" c* R$ V  <<hex<<hres<<endl ;
: o. U0 }, S; ?( R8 g$ S  pLoc->Release(); # G0 h2 c5 L0 D4 r7 X2 k
  CoUninitialize();
% {& _0 H; N/ X' i/ L  return 1 ; 3 f; ]$ e/ X+ C& T
  // Program has failed.
& A+ `: C  ], d- v. J5 L  } & |% D: H1 a, U8 f5 l9 @7 ?  X$ R
  4 Z, P; a7 O! |, _. S" _$ B
  cout<<"Connected to WMI"<<endl ;
+ y7 ?, p- L5 F' N- K6 ]  
4 Y- ]  H  L2 b+ r  // Set the IWbemServices proxy so that impersonation of the user (client) occurs. 8 @& m. o& _& u+ X
  hres=CoSetProxyBlanket(pSvc,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,NULL,
: }+ }% s% \1 s5 o# E5 d  RPC_C_AUTHN_LEVEL_CALL,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE); + g& c- _. H* O' d  A3 [, Z* O
  
- d8 f+ b; f) D, b6 t  if(FAILED(hres)) 9 H. P, Y- L- [  N1 S
  {
& f' u9 _& X3 m  cout<<"Could not set proxy blanket. Error code = 0x" 5 ^$ ^; j9 p5 M. o$ U6 r
  <<hex<<hres<<endl ;
( p2 E2 v+ j$ G1 L. Q+ f/ }9 {  pSvc->Release();
5 v3 s! u5 M4 x  pLoc->Release();   r, U9 s8 @) D0 ^- A. `4 ?7 q4 r2 [
  CoUninitialize();
0 p4 D7 E! @8 p! [  return 1 ;
6 G) n1 ^" Y* L+ z  // Program has failed.
) v4 y+ ^: \6 F4 V) }9 T( j3 u  }
  W2 p( [8 x; k' m  9 a9 f* C3 q* ~& T/ }
  
; M2 i2 R3 H8 h  @4 r& f3 k( U) I  // Use the IWbemServices pointer to make requests of WMI.
- o5 T; U5 S; E) c  // Make requests here: * o, ~0 E; }% K- c- j/ g
  
# L1 k. \8 {! V3 r' D: s  // For example, query for print queues that have more than 10 jobs
3 }0 I2 F( F: y  IEnumWbemClassObject*pEnumerator=NULL ;
3 z, X' ]/ U+ a0 R, J# L  hres=pSvc->ExecQuery(
- T8 f2 [$ o2 N- r  \8 Z8 y/ b; h4 x* |$ b  bstr_t("WQL"),
$ b- `" Z* [/ Z& E! |  bstr_t("SELECT * from Win32_BIOS"),
/ z( N% b0 m) }  WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,
6 ~. V7 V1 t, d# }  NULL,
% w! D  ^& N/ R* l5 i$ x& @7 Y  &pEnumerator);
& k' ]0 V7 e- I" x/ ]6 u+ h) x, A  
' V/ M8 ~6 S; e: V3 B! @) p  if(FAILED(hres)) 7 ?% u% V# x3 T$ w
  { - ~1 T0 d; K4 B3 ~2 T$ B2 a) A
  cout<<"Query for print queues failed. Error code = 0x"
3 _' V# O0 V0 n  <<hex<<hres<<endl ; 4 v' t5 d- G$ w% v# ?
  pSvc->Release(); ; i6 Q6 ]- j) J" a+ M
  pLoc->Release(); - ^/ t0 Z7 F" p% z  I0 i" ^) \
  CoUninitialize();
% H& }% S1 f$ Y, a7 P3 U& n  `" i  return 1 ;
' O5 S" n' x2 v  // Program has failed.
) a- H$ i% Z0 I  } + g. r: v, b8 |0 W
  else * X' E+ M* g9 ~/ D: A% ^
  { $ i3 v% @2 N" a8 N* f; V! z
  IWbemClassObject*pInstance=NULL ; " k. X! k0 a) W  F: F) i
  ULONG dwCount ; 2 X" }  g) B5 l
  while(pEnumerator->Next( ( j; i) V* m5 k
  WBEM_INFINITE,
. A# \6 ?7 X1 I: ]# g  1, 9 d; s/ q0 w9 v. ]8 h
  &pInstance,
1 ^$ j4 n2 n! F% A% j+ J" D  &dwCount)==S_OK) 4 V5 l% \9 `, W5 A3 |/ P0 Z
  { ) q4 X% @' y9 N7 w: k
  SAFEARRAY*pvNames=NULL ;
3 J' f# _' J. a2 L$ b  if(pInstance->GetNames(NULL,WBEM_FLAG_ALWAYS|WBEM_MASK_CONDITION_ORIGIN,NULL,&pvNames)==S_OK) 4 x& `$ [# \4 c" V# I0 A+ O
  { 3 Z. f0 H7 ~' j2 Q7 x6 H
  long vbl,vbu ;
8 e' V2 \" `3 |0 y  SafeArrayGetLBound(pvNames,1,&vbl);
+ Y, D5 P# t  O% y- e! T2 i/ s1 c  SafeArrayGetUBound(pvNames,1,&vbu);
' J  |) G  y9 r& x2 f, K  for(long idx=vbl;idx<=vbu;idx++) 3 H: S3 S, D$ ^5 b
  {
9 t4 U; i' Q; i, Y- r  long aidx=idx ;   Q* W4 Q0 C. S2 L3 w$ C  V& E
  wchar_t *wsName=0 ;
$ T( q; u* ], [" }% x, G- D8 E  VARIANT vValue ;
! Y3 G( g# E7 d  VariantInit(&vValue);
& a, u& v) u6 u7 W* |; ^  
' P2 B5 j, G; m; x6 ~' {  SafeArrayGetElement(pvNames,&aidx,&wsName);
3 d; y4 l! Q  u! E! X: z9 y  
  {* y3 v6 M5 a+ X  BSTR bs=SysAllocString(wsName);
8 q, G+ L) C* ]$ p$ W5 [9 s( s7 |! I  hres=pInstance->Get(bs,0,&vValue,NULL,0); ( ~# x% M3 X8 T* e
  SysFreeString(bs); ; P: C" Y7 ~8 d( Y& }) I6 Z8 M
  
# M# b0 o& X% d2 A2 u) w4 z/ R- Z" V# t  5 p  M. f- V6 f+ L
  if(SUCCEEDED(hres))
" c) ^; p( I+ D# m$ D) w  _( @  { ( S! G' s2 W# r/ M; I5 O% X
  char szANSIString[MAX_PATH]; $ \% z9 m/ a! Z& D$ `) @2 G. |
  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,wsName,-1,
) u4 C* b1 ]. m7 w$ v  a  szANSIString,sizeof(szANSIString),NULL,NULL);
, S/ R8 [+ r- P  
1 G+ y: U8 C) ]5 t% u0 l' t  cout<<szANSIString<<" : " ; : D  g7 k# t" A6 C
  switch(vValue.vt) # q2 _) ]8 i& o% u5 a2 Z
  { # k4 i( M/ K+ F" F
  case VT_BSTR : : j$ `  j3 f  e/ z2 _# ?
  wprintf(L"%s",V_BSTR(&vValue));
) k7 E+ C8 l; j* d% A8 ^  break ; & ]: b" @: M" {* y' G
  case VT_I2 : $ [, P1 {% s( W7 H
  wprintf(L"%d",V_I2(&vValue)); ( }$ K9 W! y* p
  break ; 1 K! [8 \3 Q* Q) {) B$ j
  case VT_I4 :
  F- M) m6 Y- n7 V" V5 x  wprintf(L"%d",V_I4(&vValue));
4 U; G5 r  z7 i; _4 Q0 z+ {  break ; " m! w4 G2 T4 N1 v  E* y
  case VT_BOOL : ' s+ {. X) {) X  v% F( T" H( o
  wprintf(L"%s",V_BOOL(&vValue)?L"TRUE""FALSE");
  \4 P8 v( z5 Y2 D$ u% ~  break ;
4 k4 x! b/ T6 ?; n) e& ]/ g  default: - q* x. o6 h& G7 Z; e' b3 B
  /*WCHAR tmp[100]; * D- M/ |* D. X& ^0 R, Q: u9 J
  wcscpy(tmp, V_BSTR(&vValue));
) Y* f" D- @; l& ]  char tmp1[MAX_PATH];
2 @  l( r) H3 b6 E3 v+ q  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,tmp,-1, , v2 n* L) t8 e! W6 S! |0 i
  tmp1,sizeof(tmp1),NULL,NULL); ) Y1 a& L. o, W; o  ^* E" \/ g
  $ I% Y8 ?& j* z3 |; E" y& F
  cout<<tmp1;*/ ' L3 m0 D) D9 }/ u, y8 b( G0 l
  break;
! t; l3 }* W3 m/ X/ D4 @  } 9 S$ q' ?+ a! b1 w
  cout<<endl ; % J6 c4 B5 B. M" v( R1 X
  }
% K$ W/ {3 H# z! i/ X  
5 p% I" c) b; @$ J2 ]0 t1 ^) l. x+ Y  SysFreeString(wsName); , H$ r6 Y: f% V. X) x# p+ r
  }
. _7 j; [7 n  t4 W8 O1 a$ C  
& w3 h* v0 i  v6 ?( e1 O# V* H9 R+ l  }
. G. D1 ?, C" y/ [1 \  else
) s9 y% x% ^& d' V8 N1 P; T  { ! G$ o2 {0 \& }$ D- A
  cout<<"Query for print queues failed. Error code = 0x" ! H  @# l( U( t  v9 o: B
  <<hex<<hres<<endl ;
0 u5 l  m# P' Q+ ^4 e3 A  pSvc->Release(); / S! W2 J! m1 \
  pLoc->Release(); 3 N8 O4 y5 |' k8 `1 B
  CoUninitialize();
- f4 F4 {& I3 d; g, ~/ M3 f  return 1 ; / ~6 ]: B& ^/ O, ]7 R
  // Program has failed.
$ b! ^3 N2 v1 i* y  } / e1 ~6 `% s# A
  if(pvNames)SafeArrayDestroy(pvNames);
! Y; \& ^$ ?$ r1 S- x3 C  }
, ~+ C! v& D) ~% R+ ~  if(pInstance)pInstance->Release(); % ~8 c% i5 `$ W4 T" {  n& p$ _2 A
  
: c. I" E) T" I. ~3 g' O0 n+ K  }
( G$ \$ G3 Y- e0 C5 Q) h3 y  // Cleanup . @, V5 z( [2 r  {
  // ======== 7 f  h2 A$ i$ e0 w( R
  pEnumerator->Release();
4 h% g2 H* O. C5 @' X6 K: r  pSvc->Release(); + [- C" h6 s! o+ B% ~! A. Y: _
  pLoc->Release(); * |$ z6 O9 d" R9 U
  CoUninitialize();
  |3 {1 \/ J- }0 a4 _9 V  
6 J' W7 t/ ~# o6 N! t" Q  return 0;
+ x2 H; {+ r6 z) c/ g  // Program successfully completed. 9 a  N/ M: X  H+ F& ~- `
  }
6 J1 C1 p- G6 C+ U* J  k  //-----------------------------------$ j* W+ I/ q+ b3 c
  0 ?" b, F# D* \# u. }
  对于怎么用BCB编, 感觉还容易一点,因为我在类型转换的时候碰到了一些问题,而在BCB中的Variant类做了比较好的封装, 具体代码可以 http://www.cppfans.com上找到. " C1 x) s4 M3 Q% B( J) k6 {
  ; }/ |' N$ k# h8 m
  void GetWmiInfo(TStrings *lpList, WideString wsClass)
6 ]& Q& v5 l' v0 _1 D( D  {   y+ K8 W6 \  ?4 v" p
  IWbemLocator *pWbemLocator = NULL; 3 H7 y# Z& B* o1 x0 r  D4 d. x9 @0 Y
  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK) + {6 I, u$ E6 K7 v( d! L
  { 4 {- J' Z# m: \" m, K
  IWbemServices *pWbemServices = NULL; $ X' k( o- r9 Y3 J. w- K7 b0 o1 d
  WideString wsNamespace = (L"root\cimv2"); & S  v+ [- G7 k  t0 T$ J
  if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)
4 S* f7 v5 b, P5 o' [  {
3 X9 |; P; l9 M- L* c  IEnumWbemClassObject *pEnumClassObject = NULL; " b0 c. N: L9 B0 S4 k  p
  WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;
; `& |- M5 X8 j( a6 }* Q: I5 b  if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK) 8 \1 e$ Q; a5 Z+ ^0 d" P# [) p6 w
  {
9 G1 |! _/ w% [7 F( H  IWbemClassObject *pClassObject = NULL; 2 q, Y* P5 J% O1 C( A; p$ K" @
  ULONG uCount = 1, uReturned;
" E! Q9 \/ d/ m7 q" D8 ^  if(pEnumClassObject->Reset() == S_OK)
" q+ Y% a9 {, K  { ; c! B' W* R& x7 l
  int iEnumIdx = 0;
2 d; g( `1 r$ q  r  while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
+ E% H- E( d) T1 U; `# @1 L  {
/ T: E2 A7 O) n. |7 H" B9 K. r  lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------"); 6 J/ T: X* D; K, v4 U; t
  
) ^/ `# J& K) u" ^# a! }" \  SAFEARRAY *pvNames = NULL;
! H# G4 i& Q6 {* J  if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK) * ?5 J* W" J6 _. P
  {
; O0 O$ x" x$ W  long vbl, vbu; 8 G4 J& J, E* L
  SafeArrayGetLBound(pvNames, 1, &vbl); . T, C4 A6 e& R* x7 j
  SafeArrayGetUBound(pvNames, 1, &vbu);
; t- B+ h5 v' p' g  for(long idx=vbl; idx<=vbu; idx++)
+ J$ @% r& c: O! V% g  {
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-11-14 18:13 , Processed in 0.017686 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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