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

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

[复制链接]
发表于 2006-4-16 18:40:38 | 显示全部楼层 |阅读模式
    一直以来都没有用过WMI, 都是用的PDH来获取系统信息.感觉两者很些相似,都是类似于性能数据库,基本的一些什么硬件软件信息都可以比较全面的获得.只是用VC来调用相对比较繁杂,用VB和C#就方便多了.这些天到MSDN上找了些资料,总算大致搞清了一些编程思路.对于那些很想知道怎么获取诸如CPUID,硬盘ID,BIOS信息以及主板信息的人来说应该有些帮助吧.试着用MSDN的例子乱写了一通,以下是通过WMI获取BIOS的例子,不对之处还请指正 ^_^:
( m- h. u+ p+ v1 y( R2 P* k  --------------------------------------------------------------------------------/ c9 _/ C; P' R. x
  #define _WIN32_DCOM
; Y2 L" f# P) i2 A  #include <iostream> ' Q' V" k/ j! Q5 X
  using namespace std ;
) q( l+ A3 Z3 n# P  #include <windows.h> ( h8 U9 B1 Y  P9 o
  #include <comdef.h>
) h3 A5 q( e6 F1 U& d0 }6 ~  @  #include <wbemcli.h> , u; ~  {; x+ ?' }7 E6 j
  
$ F* H& q/ N6 E+ I  `! m  #pragma comment(lib, "Wbemuuid") 6 }) m- \2 {: @
  + ~& m: Y7 b1 L
  int main(int argc,char**argv) / c5 x; m& r9 `6 I" d* z
  {
4 I  H% \, }& f, M+ e  HRESULT hres ;
& I! D, A- w7 i4 w  : N9 s' M" C0 }3 J! c' \: k
  // Initialize COM.
6 d1 L/ _9 U! L; k: i  N  hres=CoInitializeEx(0,COINIT_MULTITHREADED);
" E9 Y* q9 c9 d6 `1 V  if(FAILED(hres))   e9 h9 p. B8 \  J' |2 m! m0 _
  {
( H& e% V" _3 A# C  cout<<"Failed to initialize COM library. Error code = 0x" 8 m2 X+ y0 w5 y& b% G- V. m+ U1 `
  <<hex<<hres<<endl ; 9 K$ Y* I/ V  U0 Z8 `) V+ a
  return 1 ;
$ p8 ~2 }  Z% r, F5 b  // Program has failed. ! n1 |; k6 `% `5 N: H
  } 8 k' ?, j% p- E& a3 T
  
4 p) D# {7 h. P9 J# Y  // Initialize % Q% c- U1 |9 P3 O4 I" f, @$ Q
  hres=CoInitializeSecurity( 8 l: Y. U. s6 _; T0 B
  NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_DEFAULT,
3 Q: |7 o* T* Q. I% `, l  RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE,NULL); . a. C+ J2 Z$ Y8 m
  
; Q3 Q. ~2 {  F' F- \( K5 B& u- |$ O0 Y  * j; c- b! Y) |! B0 u' M$ C) U
  if(FAILED(hres))
7 j. j. b. u) J3 J' y# b  {
; ^  D/ I# J: X" L2 y! S  cout<<"Failed to initialize security. Error code = 0x" 9 W+ v; _1 j. a+ D, i+ [
  <<hex<<hres<<endl ; 8 B* T; R3 K% a8 E
  CoUninitialize();
  q4 e6 M7 Y% R- B  return 1 ;
  q, p5 x* X$ f  // Program has failed. . H) V6 z9 S0 {
  }
8 a# Q) S; G1 Y. o; L    S4 E) x, F2 o( r; V& H4 i
  // Obtain the initial locator to Windows Management on a particular host computer. + e% K  n9 A3 S3 ^5 [2 C+ U+ x
  IWbemLocator*pLoc=0 ;
7 @6 Z6 o4 k9 a; A% @  
8 X$ u0 k  b, ^& i( A  hres=CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER,
9 u: ?4 {# o8 _  o$ m7 M  IID_IWbemLocator,(LPVOID*)&pLoc);
3 m! _0 @. j- A8 T3 G1 B  ; w! Y  G; T! s: L% J1 t( x
  if(FAILED(hres))
; k: X) G' b/ W9 C: W: u  {
- ~2 h2 {. h% m+ W0 W! w  cout<<"Failed to create IWbemLocator object. Err code = 0x" : @% \$ a8 E( U: _  E+ M
  <<hex<<hres<<endl ;
" q3 n& o8 y4 Q8 F) z  CoUninitialize(); ; F( w5 H* }( y9 I
  return 1 ;   F: e7 J8 b. P3 O- L
  // Program has failed. ! m+ t+ r. {8 @# E8 K" G
  }
" `* K1 [( M8 x" G  # G0 E2 E( F! ?9 u0 |. d& i
  IWbemServices*pSvc=0 ;
) K2 M7 ]) \; F; y& N" ?, r  & v" v( V2 ?  q5 ^+ `
  // Connect to the rootcimv2 namespace with the current user and obtain pointer pSvc
5 [; _- w3 z3 x. C3 G; @9 @7 J/ D6 m  // to make IWbemServices calls. ' m0 x- m% o  r
  % a3 \3 K9 S9 |
  hres=pLoc->ConnectServer(_bstr_t(L"ROOT\CIMV2"), / z- _  W  N# C+ k4 z
  NULL,NULL,0,NULL,0,0,&pSvc);
# y/ h0 }. {. w8 b: V    H7 M1 U( ~5 \5 c  r
  if(FAILED(hres)) . n0 Z- k7 u0 G0 H+ D6 [# f' f
  { * K( D) O7 ~1 d4 P% X4 A# d6 E
  cout<<"Could not connect. Error code = 0x"
8 d! P5 {7 h! R9 r/ Q3 \$ s  <<hex<<hres<<endl ; 1 l; G  h& T$ z4 n8 J% [
  pLoc->Release();
% f/ Q2 b. S0 r9 n  CoUninitialize(); 1 m8 p+ u2 Z) o! I5 x- U
  return 1 ;
7 U/ L* t4 k2 e: u/ R2 V' n  // Program has failed.
( d* r4 p; z* V) d8 y( o  }
; {& W! _# w3 B3 X( [  6 t) {$ Z5 z. v( E
  cout<<"Connected to WMI"<<endl ;
% _2 F$ l& V- W9 U. `  # {$ x/ e3 W) ]  L) o$ R$ U8 d
  // Set the IWbemServices proxy so that impersonation of the user (client) occurs. 2 ^- I- s! ]5 L( y
  hres=CoSetProxyBlanket(pSvc,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,NULL,
1 Z5 y6 W* [" t/ o  RPC_C_AUTHN_LEVEL_CALL,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE); 7 F7 @0 H2 P3 ]+ c( p' Z
    \  D/ `) D& _" n
  if(FAILED(hres)) , @' x( |; s' l2 d" X% f  t
  {
) V3 Y4 v5 Q' j  cout<<"Could not set proxy blanket. Error code = 0x" 2 r' N6 o  {0 G' _
  <<hex<<hres<<endl ;
! P6 r- l! i" i8 b' @: h0 D+ B. D1 M! P9 ~  pSvc->Release(); % A0 n7 R# b7 a  e0 k
  pLoc->Release();
6 d& W' w1 M1 V8 D  u; `# P  CoUninitialize();
3 G/ q; g% k9 ~) n  D  return 1 ;
/ J. h- A: u. T; W9 x3 J  // Program has failed.
9 r( E& R/ _% D) i( S3 m. U- I  } . X7 v0 g) B7 I- ~, Z
  ! {& B1 Z6 B& \# j& r) P
  
+ @, g/ y4 e$ _: Q* T  // Use the IWbemServices pointer to make requests of WMI.
, {% S2 o$ G% W& O  // Make requests here:
( V- w8 _* s4 r4 y' d! Z1 e  ! Y2 x# I( C: p& s
  // For example, query for print queues that have more than 10 jobs
/ k1 Z  d& |; b: u5 M$ m  IEnumWbemClassObject*pEnumerator=NULL ;
, ]0 S: T+ R; ~' R/ a% g7 E  hres=pSvc->ExecQuery( 8 F  w% t, k3 {' C+ Z9 D
  bstr_t("WQL"), % u* m0 I* r! J+ N# N1 ^4 c/ i3 P9 B
  bstr_t("SELECT * from Win32_BIOS"), 8 V9 f: b" [" B
  WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,
% i) B6 Q4 Q) l. x: b5 f  NULL, - S7 c% O- s; p- Q) v) _1 K
  &pEnumerator); 3 \3 T9 ?0 _3 z  o
  
# V% d& Q& z  h+ Y( t' E! n  if(FAILED(hres)) : j2 K; a# L; O1 Z: k6 p" |2 H: ~
  { - S8 m* _% v! m  c3 T# L
  cout<<"Query for print queues failed. Error code = 0x"
7 b0 k4 @; M$ e  <<hex<<hres<<endl ; 6 W" a. f$ O& [# Y* [
  pSvc->Release(); $ i9 _4 |. G+ I- r" J
  pLoc->Release();
9 M7 x( L! Y- ^& r# P  CoUninitialize();
  {+ s5 @) o3 r+ \1 a  return 1 ; 8 L$ _8 a8 a/ C9 m
  // Program has failed. ( C( E6 t5 {  _
  }
1 x, L& d5 u( v1 a- n  \  else 2 k, T1 d/ P' j$ e
  {
! K* L0 R0 f% f' k7 d; n, Y  IWbemClassObject*pInstance=NULL ; ! n. c) B: j) O: r
  ULONG dwCount ;
2 D# y# v% x8 p  while(pEnumerator->Next(
( f" W6 d/ ]8 c' ^) G9 ]  ^  WBEM_INFINITE, : v4 g: v, A$ R+ W5 t6 w/ Y
  1,
; r' Y3 r# h! n. S2 ^4 \  &pInstance,
+ q" J  @/ W: [" `0 j  &dwCount)==S_OK)
: y/ f! j# }. B+ I% {+ m  {
8 S. N4 o7 Q9 n  SAFEARRAY*pvNames=NULL ; 0 N( @+ m1 i7 b& k! D0 U
  if(pInstance->GetNames(NULL,WBEM_FLAG_ALWAYS|WBEM_MASK_CONDITION_ORIGIN,NULL,&pvNames)==S_OK) , x* U, y- ~7 ^/ e1 f5 O' q6 l
  { + D& V2 \. }$ _" }- a  T
  long vbl,vbu ;
( J' W1 ]9 K+ N: R* ^( B5 y4 g0 q  SafeArrayGetLBound(pvNames,1,&vbl);
/ X: q( C& Y, _/ z0 y& T  SafeArrayGetUBound(pvNames,1,&vbu); - y! [8 E5 V, Q; z* P- a8 h. v
  for(long idx=vbl;idx<=vbu;idx++)
! T) h, A8 s1 R0 H. i0 x  {
3 N! @% v& p! M; g5 R1 L  long aidx=idx ;
6 j% v8 [9 ]1 p/ N  L  F  wchar_t *wsName=0 ; ; o! P* C: S! O' j2 K
  VARIANT vValue ;
* u& v" n; g/ M; I: J+ H2 o  VariantInit(&vValue);
0 X9 R- w* R! y/ K  0 I, D; z6 j$ E* K1 \  Y/ D
  SafeArrayGetElement(pvNames,&aidx,&wsName); 0 N7 T3 o& y5 o  `
  4 \  J' k3 q; k2 i1 u$ p
  BSTR bs=SysAllocString(wsName); 0 r+ c# ?2 B* ]/ ~" @
  hres=pInstance->Get(bs,0,&vValue,NULL,0); 6 X6 ?2 L$ k1 e
  SysFreeString(bs); : f+ a) O' E+ P; h; h
  
- R$ V% j8 }0 @7 d$ Y* U  
: U4 }" I$ a4 ~/ U5 G! J  if(SUCCEEDED(hres)) % y& Z! q  ^+ c' c1 i
  {
6 `, a8 R0 c4 L; m& u* S! g$ x  char szANSIString[MAX_PATH]; , g3 R- k- \" V+ P7 Q5 b8 o) \6 ~$ z7 C
  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,wsName,-1,
0 K0 b# i4 Q3 Z, \  szANSIString,sizeof(szANSIString),NULL,NULL);
- b0 z% w. {, {$ e  & J# N9 ?- R# F8 X3 O+ J
  cout<<szANSIString<<" : " ;
8 b8 q0 T( @5 D" I( G! D& p  switch(vValue.vt) " U- p  _6 F0 T# X: F  C# K
  { / s/ ^+ z; P$ k' Y" M$ M  `
  case VT_BSTR : $ D- l  p4 K) F6 ~+ l+ [
  wprintf(L"%s",V_BSTR(&vValue));
1 G7 K: P* N! q: L9 m6 {' W8 O7 i  break ; 8 E7 W8 V: w, d* F0 g6 c
  case VT_I2 :   g2 \* c" q/ c  x2 S. i
  wprintf(L"%d",V_I2(&vValue));
. S* a5 S1 W9 N6 Q& a/ c  break ; ) M9 e5 ~+ L. M/ R0 Y6 u
  case VT_I4 :
' s8 A' g3 j4 G9 t7 c% A9 v; K  wprintf(L"%d",V_I4(&vValue)); , n0 x* L+ t- r* [& Q3 U' u0 ^
  break ;
' r5 |  D! x% G+ `# b  case VT_BOOL :
- d) e3 }# a" f# y! C  wprintf(L"%s",V_BOOL(&vValue)?L"TRUE""FALSE");
: C" [- ]1 O. S. i' \  break ;
) X4 k" C. R) s  default:
, ^- H  G$ h8 L1 `9 N& p* h  /*WCHAR tmp[100];
- y, `! `6 m9 z+ B1 `' v  wcscpy(tmp, V_BSTR(&vValue));
. g) G5 B; ]  ^& r0 L; z7 G  char tmp1[MAX_PATH]; 9 ^5 A/ V) D* Z1 }% w
  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,tmp,-1,
1 C) r5 f6 E$ A! _# I$ |( L  tmp1,sizeof(tmp1),NULL,NULL);
9 @; F# A( O1 T1 C& T/ j* W  ( f) D& C6 q& M
  cout<<tmp1;*/ * T8 d2 p+ m/ D! r% V- y- i
  break;
( w" @6 A  k2 g3 }, }  } 8 z. v+ O& t- n
  cout<<endl ;
5 E7 {; s$ S3 q- K! G  } 8 _7 I5 L, G, |8 I/ S) A4 T4 D5 b
  
6 Z& I4 n0 s5 q# ]; ~  SysFreeString(wsName);
! H5 ^; q4 Q0 X3 i- L  } 2 c! H  N- A# f
  
5 i6 Z9 Q: B# {  X( U4 H* J! ^! F  } & T# s% V* E- _: W
  else
4 @, t# Y5 [- h+ S: |  {
& H) O. R  A" L/ k& k  cout<<"Query for print queues failed. Error code = 0x"
  v- X$ e2 H; B" C" F; }  <<hex<<hres<<endl ;
6 p+ U; \$ W5 {* X  pSvc->Release();
7 W- a7 q; ^& ], q# t' X% [/ a  pLoc->Release(); 2 s- q; A# a+ r
  CoUninitialize(); # L" S2 ^  c, \: g
  return 1 ; # Y) z" s& R3 O' R6 w: r
  // Program has failed.
7 y9 k& x# C6 B, n5 }- f, s; L  } 2 n* h/ y% S* o/ B) C
  if(pvNames)SafeArrayDestroy(pvNames); 4 q. y1 I5 r  O& j
  } 8 ^/ X& M; E& H3 G$ H& e
  if(pInstance)pInstance->Release(); $ I- @; z7 s) s! M1 U+ b. b: V
  
1 s& C# {. r; l" Z  }
9 ~, j5 [5 s1 L/ q9 d$ Q( d  // Cleanup   h3 T6 W: c. |: l6 i9 j* H6 W
  // ========
0 w  f1 ~8 f' Z' c3 I  pEnumerator->Release();
% ?3 f1 I# c; ?  pSvc->Release(); 2 I* e9 U6 ~( P) n- q' \
  pLoc->Release(); 8 \) U( p6 C$ L
  CoUninitialize();
% Z0 x4 K/ ^4 J( d0 ~0 l  % O$ J9 e6 X6 {
  return 0;
0 I3 {! ?; s1 v. _( g& W5 ~  // Program successfully completed. 1 Y4 K( b" I8 ], e) y
  }
- e  P) X; o, e2 O  z7 u  //-----------------------------------% O: D) D# q/ m2 e0 T/ e  p3 G1 V+ S
  - _% F7 \# Q' U
  对于怎么用BCB编, 感觉还容易一点,因为我在类型转换的时候碰到了一些问题,而在BCB中的Variant类做了比较好的封装, 具体代码可以 http://www.cppfans.com上找到.
# e+ z4 P# ^' g. V3 i  
6 p" T* ]8 i7 C1 M  }  v, E- u  W* t  void GetWmiInfo(TStrings *lpList, WideString wsClass)
4 K+ N( X. b3 r( s7 |5 Q  { + [* r4 V+ y* X9 L: \
  IWbemLocator *pWbemLocator = NULL; 2 u7 X6 i3 o+ @# I. f+ v/ s4 P
  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)
7 o% w8 n6 n! |4 }2 b6 }7 V  {
3 D8 K% e% d5 L5 o1 R  IWbemServices *pWbemServices = NULL;
0 q5 v- o5 z3 d  WideString wsNamespace = (L"root\cimv2"); 7 l. M) ?* }2 S3 y) s" `
  if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)
- @2 ], Z( w" |1 m8 Y  { - ?% Z( R2 r1 U
  IEnumWbemClassObject *pEnumClassObject = NULL; 9 m4 Y: P! O1 E. h9 ]1 g8 K
  WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass; 7 K7 n5 F1 w5 ~' T* q
  if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)
' v; ^* s; m; x, k  { ) M4 ]0 b6 f5 q' M, I1 c; }
  IWbemClassObject *pClassObject = NULL;
4 G- |0 k& y9 F; }; n  ULONG uCount = 1, uReturned;
& V$ y; @- L, V0 D% }5 t  if(pEnumClassObject->Reset() == S_OK) 5 c# v& H% j. v5 c( V/ W
  {
5 I" S& M3 L* G  int iEnumIdx = 0; 5 X5 k, `, R' M7 Z  U) H
  while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
4 V& J2 N' g2 u8 |! P  { 3 j5 j7 \5 a% a+ T
  lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------"); 4 Y" s% s& n) Z
  4 z! h% [. O' k& Q  F# ~' n
  SAFEARRAY *pvNames = NULL;
. ^: Q; z3 b# }* d" }- n6 H: W  if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK) 4 Q, K- g$ l, W2 i( k
  {
* U2 E6 R+ C8 L: s# ~  long vbl, vbu; 1 v: W, S! h8 `; |/ R
  SafeArrayGetLBound(pvNames, 1, &vbl); : c, i4 M  O$ z( p4 V% d
  SafeArrayGetUBound(pvNames, 1, &vbu);
7 s& c1 Y, w& }7 \  J  for(long idx=vbl; idx<=vbu; idx++)
. m' P1 G* ?; r! F( H+ l  {
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-5-2 10:20 , Processed in 0.018751 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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