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

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

[复制链接]
发表于 2006-4-16 18:40:38 | 显示全部楼层 |阅读模式
    一直以来都没有用过WMI, 都是用的PDH来获取系统信息.感觉两者很些相似,都是类似于性能数据库,基本的一些什么硬件软件信息都可以比较全面的获得.只是用VC来调用相对比较繁杂,用VB和C#就方便多了.这些天到MSDN上找了些资料,总算大致搞清了一些编程思路.对于那些很想知道怎么获取诸如CPUID,硬盘ID,BIOS信息以及主板信息的人来说应该有些帮助吧.试着用MSDN的例子乱写了一通,以下是通过WMI获取BIOS的例子,不对之处还请指正 ^_^:
' @  a# R8 W* u$ \  --------------------------------------------------------------------------------
5 O, M+ R: s  z  #define _WIN32_DCOM * j3 l+ r* p( B5 q2 F" ?+ y8 }& }
  #include <iostream> : k, E9 \9 l8 ]0 T, l0 v7 ~
  using namespace std ; ( I$ z) Q! t" e( k7 H
  #include <windows.h>
: l( m/ k2 o8 W! x6 w  #include <comdef.h> 0 r& }9 ]6 v4 J3 M( ?; Y
  #include <wbemcli.h> 9 i% d6 h* ]2 d+ z
  7 T% H4 J5 T% w
  #pragma comment(lib, "Wbemuuid") 0 r' ]2 i9 X4 R8 W
  
8 ?' u& }) ]5 w2 ^  int main(int argc,char**argv)
4 ~' [  `: N- x# B5 D8 P  {
" O0 a$ \! _4 `9 D/ s  HRESULT hres ; % Y, }5 f% t1 E" w* `, S
  4 i7 J; u4 J6 M. t( S/ _# |
  // Initialize COM.
6 g" c; @0 q! c1 {2 }  hres=CoInitializeEx(0,COINIT_MULTITHREADED); + R4 y& v3 b7 k* U9 m, s
  if(FAILED(hres)) , P/ U! |9 O8 N9 ^! I2 Q
  { & J4 {' U7 \6 v, p
  cout<<"Failed to initialize COM library. Error code = 0x"
. H& M2 \5 {5 n" q1 _  <<hex<<hres<<endl ;
% _1 k9 T5 j5 Z, `; M6 x, I" z  return 1 ;
. [9 @; H0 q& L" g9 U3 s8 Q  // Program has failed. ' z  H& p; S: M. C  W) v0 l" O
  }   Y. {. X( f& i4 c
  
! {; S0 X) w- s4 v# Z  // Initialize ! c$ E% d0 w2 `2 V% S  u- Z+ w
  hres=CoInitializeSecurity( 0 p6 S+ d) t7 ]: _! z1 ?* E$ _3 f
  NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_DEFAULT, # O0 ^9 I. t' H' I. l
  RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE,NULL);
' a4 N7 G1 m: p. G$ v0 q: ~, k& }  
# o& g9 T! G& w0 q  3 e5 p1 S  B9 ?+ C7 \% K9 a
  if(FAILED(hres)) " j( w: @" @, W
  { 6 x! f8 r3 b* t% K5 g& @
  cout<<"Failed to initialize security. Error code = 0x" 4 w; Q9 W2 G: c2 j1 V' v
  <<hex<<hres<<endl ; ) A& J1 m. X5 A4 b
  CoUninitialize();
5 d* w7 k8 u# d" T, z  |0 o  return 1 ;
) D) y2 E/ W! I, E1 C# \& ~& ?' n  // Program has failed.
) L# n* ^! r3 b  }
& l: s* n( x- t1 A4 X0 d  * ]. p; k9 h% a2 Z1 |
  // Obtain the initial locator to Windows Management on a particular host computer.
2 E) i3 i4 C! f8 a, f& V  IWbemLocator*pLoc=0 ;
$ Z3 O( d- \' w  2 D2 D* R. i9 P/ n" w. U$ J% L! B
  hres=CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER, - G6 b' g9 r/ `
  IID_IWbemLocator,(LPVOID*)&pLoc); ; Z+ U& q4 I# g& \4 }" b" Q6 u
  
( \2 H9 j7 b7 v$ j' _  e  if(FAILED(hres))
5 h- v4 S0 K/ [  {
1 J& J9 I& Y' ~/ G% L, O2 ^  cout<<"Failed to create IWbemLocator object. Err code = 0x"
( C* U; I& j/ x* B  <<hex<<hres<<endl ; 7 P* B2 S+ M; w% B  q" e+ d
  CoUninitialize();
8 l( e& ^- c% p0 Q) |- h2 w  return 1 ;
: @- `% K1 j8 W  P; \/ _  // Program has failed.
' s2 L4 H' P# U# i6 F6 D  } - f9 j9 V% }: |
  
3 X+ }+ M8 V8 V) g$ n* T* d  IWbemServices*pSvc=0 ;
9 w% x# A& ?5 [! Z! M, u4 @  
# S1 l& j4 v/ t3 w  // Connect to the rootcimv2 namespace with the current user and obtain pointer pSvc ( t6 R+ a( n2 }0 Z' Y8 S
  // to make IWbemServices calls.
  p6 l8 z. Y* T6 X  ' C  i+ v( C! `5 S6 f0 ]2 E
  hres=pLoc->ConnectServer(_bstr_t(L"ROOT\CIMV2"),
4 g& J1 t2 \0 ~$ t0 N  NULL,NULL,0,NULL,0,0,&pSvc); 8 g8 H% k" P% \, V3 ?/ g7 T
  
" e8 q2 R+ d) }) [  if(FAILED(hres))
7 K- Q2 ^; Z* {9 [( N$ i/ M  {
5 r; S8 h- X7 _9 N) M) ^. X  cout<<"Could not connect. Error code = 0x" ' i' X0 q. _6 r4 }7 e$ Y- v+ g- p
  <<hex<<hres<<endl ; 0 z% Z$ R6 x* o7 k# V+ o1 S, u/ V$ S- a
  pLoc->Release(); " k" N3 K; M- }% b" w  V  N7 j
  CoUninitialize(); # x# Z6 x+ N4 c$ x- H
  return 1 ;
' O2 e2 A" V& o5 v4 G; F' V  // Program has failed.
# y9 p4 \2 k8 P- E/ j" H# A4 i  } 4 t8 y, x8 u% j' R$ A8 ^5 ^9 W/ O
  2 q1 v& u/ x7 \, Z3 J
  cout<<"Connected to WMI"<<endl ; 2 I0 ^. w7 m* s
  
/ r  c4 Z6 ^2 K6 K5 B2 H  // Set the IWbemServices proxy so that impersonation of the user (client) occurs.
4 ?0 f5 _/ ?! W  hres=CoSetProxyBlanket(pSvc,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,NULL, 8 I2 j( H9 |" s/ L9 v' |
  RPC_C_AUTHN_LEVEL_CALL,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE);
7 r9 l0 W/ _( p; k" [& |6 \  
$ Y! z3 c( q$ B2 T& q  if(FAILED(hres)) 6 R" }) t1 m% Y% N/ v
  {
$ x& T# Z" o& o8 j3 H  cout<<"Could not set proxy blanket. Error code = 0x"
  W, d! o+ `" {3 Q  <<hex<<hres<<endl ; , C" u) j; J# y* x. y
  pSvc->Release(); , d; T, ]; k  P
  pLoc->Release();
: O' z* R* O- s3 b4 X* `  CoUninitialize();
% J3 T" q  p0 u( K* h. `  return 1 ; 3 y% t! ]- l! X' u
  // Program has failed.
/ L% s& F9 F% v% P  } . N) H7 S& T5 Z( b! {7 e
  
* J! a! W/ ^, Q% M. ~' g4 H  5 w+ O/ N) Q9 M' t/ |
  // Use the IWbemServices pointer to make requests of WMI.
# g" j" B. m8 a& U0 \$ Y4 X- r  // Make requests here:
( J) M6 b4 Q! W$ C# H  & R7 r; J$ Y  |! B5 l% T) S0 {. _: m
  // For example, query for print queues that have more than 10 jobs
! W9 c2 [6 d& Q" \  [6 p  IEnumWbemClassObject*pEnumerator=NULL ;
3 Q# h% K6 X) J5 h$ l  hres=pSvc->ExecQuery( ! [; s& L# n1 K- m8 g
  bstr_t("WQL"), % h' I- |* d& r/ t" p' }2 j# \- w6 }
  bstr_t("SELECT * from Win32_BIOS"), 9 D- o% Y, ?2 `5 P
  WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,
9 \  ~; Z- s) K. w. n  NULL, / O* D9 i5 }4 {9 C4 U
  &pEnumerator); 0 R, h- D. f, S5 k& J+ O
  
3 }  d% o! \2 a! Z  if(FAILED(hres))
0 W0 W3 T( q% C* Q4 _  { 6 L) P# S; w& c% N. T
  cout<<"Query for print queues failed. Error code = 0x"
) {* Q5 W9 ]% o0 T+ s  <<hex<<hres<<endl ;
% f. S! B, G+ m/ s! c) C% p- A  pSvc->Release(); ; Q+ Y# m  b2 d' k& a: r
  pLoc->Release();
- P8 F$ K6 @# a3 L$ m  CoUninitialize(); 3 S" O3 \- g9 H/ b0 i
  return 1 ; 9 U- _  d2 w, F! V- T; j9 d+ [
  // Program has failed.
0 a$ e$ V. g# V5 B# J  Q5 N  }
- N1 Q% f8 z" R) ]2 L4 `  else
$ C' C$ u& a! P  { # ~8 v, S7 K! Q
  IWbemClassObject*pInstance=NULL ; $ h5 v6 N  g) Z
  ULONG dwCount ;
. |& T! q8 A. [. q2 Q+ B. m+ e  while(pEnumerator->Next( 8 ?7 {! G+ J8 s, h% S) R4 q! Y
  WBEM_INFINITE, ' ^5 A) D7 U. F- f: n
  1,
- h, v) i: G7 _% _  &pInstance,
- R% Y6 ^' E$ p; Y  &dwCount)==S_OK) 5 {1 P8 w+ m+ j9 T1 \
  {
% ~  ?" n7 m5 M# H" `; p) }& }  SAFEARRAY*pvNames=NULL ; . x3 L: P6 L; O. ]" `) o
  if(pInstance->GetNames(NULL,WBEM_FLAG_ALWAYS|WBEM_MASK_CONDITION_ORIGIN,NULL,&pvNames)==S_OK)
, C1 m# v& a. r3 ]1 B& K9 k  {
" T( e- V1 n: H) h  A, _% o, a* t  long vbl,vbu ; 0 r" M/ G! f, X$ c, p
  SafeArrayGetLBound(pvNames,1,&vbl); 8 f. z4 t! y: K
  SafeArrayGetUBound(pvNames,1,&vbu); 0 Q( C8 z" a# ]; R
  for(long idx=vbl;idx<=vbu;idx++) 5 S9 P* t4 r  t+ E
  {
4 |, h$ {: K( V  r' R0 k% C1 e  long aidx=idx ;
* X  w% s- \: o0 k  wchar_t *wsName=0 ; 1 E5 Q6 d( j; b
  VARIANT vValue ; 7 @8 e; [1 [$ F+ U1 b# h
  VariantInit(&vValue); 9 {% A7 n: ?. h& i4 _5 Z4 ?; u$ o3 J
  % U: Q, c6 g8 s3 F! _% S" i
  SafeArrayGetElement(pvNames,&aidx,&wsName);
6 W' r/ v5 ?, e, a; S5 o) U0 Y  
. V5 o( d9 K2 E; M% e, G. X1 D8 p& q' w  BSTR bs=SysAllocString(wsName); # h9 F* B/ m( P+ z# V
  hres=pInstance->Get(bs,0,&vValue,NULL,0); 0 I8 N* J* ~+ w- z" Q' ~
  SysFreeString(bs); . q% A% M; Y" j- M' r* g/ g9 M
  - m7 u0 \; D$ B; A7 q
  0 p3 j8 \# v: C) ~
  if(SUCCEEDED(hres)) , @' q1 \5 O' O, a) L! V
  {
- b% l6 J8 ^' a# E6 C  char szANSIString[MAX_PATH]; 7 U4 \& s( P' \0 R
  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,wsName,-1, 6 v' o1 G/ z! q
  szANSIString,sizeof(szANSIString),NULL,NULL);
3 S0 f9 o0 ~' N3 x3 _' a: L  
3 k3 s2 Z3 F* \0 {  [& n  cout<<szANSIString<<" : " ;
: b0 Q# ]) n1 M7 p" S: z  switch(vValue.vt) / p6 A. J' A! g/ b& x
  { , |4 l& v2 M5 b- u6 d
  case VT_BSTR : 4 z8 l! u$ H8 w" s: B) {* b/ @
  wprintf(L"%s",V_BSTR(&vValue));
' ]5 X" Y+ G* Y3 d9 i! K  break ;
! o4 G" s/ J9 w- K! I) X+ `/ K  case VT_I2 :
. U* m2 ^4 o6 g9 |. v  wprintf(L"%d",V_I2(&vValue)); 1 c: ?# X6 P( `) j& M! l
  break ;
& M% t/ P* P4 {* S  case VT_I4 : % ~" `5 L" k! w; O
  wprintf(L"%d",V_I4(&vValue)); " L0 e% b  G8 D$ w
  break ;
6 X! q) O# t5 {# F/ V  case VT_BOOL :
. _3 M) U, C1 f  r6 E, V  wprintf(L"%s",V_BOOL(&vValue)?L"TRUE""FALSE"); 5 n- z4 k9 B3 `
  break ; 2 [* i6 z. |- j  E3 `
  default:
0 O2 p# l/ O9 [) @' j  /*WCHAR tmp[100]; # Y+ ?! C% U1 J
  wcscpy(tmp, V_BSTR(&vValue)); , |. {# Q6 S; b) I
  char tmp1[MAX_PATH]; . j, d  l* O$ P7 v2 z
  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,tmp,-1,
# ~+ N% M# j# \7 k/ s3 H  tmp1,sizeof(tmp1),NULL,NULL); $ Z7 Z1 T& {8 D$ a+ t6 l) P
  
6 t. T: T" K2 u/ W3 R( a1 j  cout<<tmp1;*/ ' ^) }6 z' [! k+ s$ V3 j
  break; 2 V2 q) @+ p. g, t( X+ q% ]5 ~: ^
  }
" n8 g9 q, l& K  g  cout<<endl ; 6 G* R! _( h, \1 A( s' A# z: q
  } % Z+ C" x, M' n: }% _+ H" V5 d2 L
  
* g4 L( j/ v& }/ \" Y  SysFreeString(wsName); $ |) f) T2 `% a' f& e* L: y
  }
" u% ~1 k/ b% n4 W$ k' y9 z3 Y  
* |! B1 a8 [6 ]: j2 c6 [* k  } ! ?. X4 W8 W3 P
  else
3 V& @9 E, T# H$ B3 L( E" ^+ m  { ) N8 [+ v. W2 T+ L% H4 w
  cout<<"Query for print queues failed. Error code = 0x" 2 T2 o5 i+ ]+ }' }0 H. l2 v
  <<hex<<hres<<endl ; 9 E( n  Z0 j* N' G
  pSvc->Release();
4 `3 e# ^2 B& A0 f2 ~5 N9 e  pLoc->Release();
$ b" y6 r6 X3 }# Z: J& M7 x  CoUninitialize();
2 w3 h& Q% i8 b. |: J  return 1 ; ) n, z5 _( C& S- L
  // Program has failed.
9 U0 J7 H$ C( G6 ^3 r  }
8 D, e1 k' m, U: q0 s+ \  if(pvNames)SafeArrayDestroy(pvNames);
+ b* e0 O! g+ G& |  }
. T) Y! f9 ]- r; l3 M  if(pInstance)pInstance->Release();
/ v/ g9 [6 E4 f2 Y  
0 i% V8 \9 N& M. P. O  }
) w% V* u8 g. U  // Cleanup ! T( F0 `* G  @) i+ p5 v8 D
  // ========
' k( ?4 o5 x# M; k% G) E) x  pEnumerator->Release(); 2 a1 }! |/ k7 I% A/ a" L( A
  pSvc->Release();
5 e$ _1 |" T8 O/ o8 p+ i: ^  pLoc->Release(); . N4 O, W9 |3 D0 _
  CoUninitialize(); ) W6 f- J2 ]8 I9 c  P" g( ?
  7 p% U6 C, J( u: P( ~$ U: d
  return 0; + W, ?& A3 R1 X! q) }! v& }
  // Program successfully completed.
" v$ r/ A) [& B  p' [0 a  }   b( b. r- p8 J1 P. u# P
  //-----------------------------------& ?( R! k" {2 P/ T' I* L
  1 S/ w1 a4 }% r: M% u
  对于怎么用BCB编, 感觉还容易一点,因为我在类型转换的时候碰到了一些问题,而在BCB中的Variant类做了比较好的封装, 具体代码可以 http://www.cppfans.com上找到. * W2 e' g/ {. E8 [# \
  
$ {$ C! u1 C/ F$ }# s' @- K  void GetWmiInfo(TStrings *lpList, WideString wsClass)
5 l5 O# `/ M" ]2 Z# l. M6 z1 U  { ; k5 }( V  [+ z) z- T
  IWbemLocator *pWbemLocator = NULL; 0 b  k/ o9 L2 B- _; \8 d* x! i9 S! u
  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK) $ G% x" e: i- e3 r
  {
5 h" Q0 O$ o% x. F4 M$ U  IWbemServices *pWbemServices = NULL; ) R# s( _9 `: j5 J% t& M
  WideString wsNamespace = (L"root\cimv2"); , w' f6 _* q  @" n- p& X) y
  if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK) & z% Y  A9 C' ]
  { 7 W# f9 N. A" @% |# \/ h
  IEnumWbemClassObject *pEnumClassObject = NULL; 9 P1 m- S9 l1 p% E: K
  WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;
$ Z* s/ k: [9 t. m3 M: F* ~/ K, B  if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)
2 c9 _! A1 Q7 J  |) X+ w7 a; a2 ~/ j  {
7 q# c, F8 r$ g3 G3 |+ q* v$ j  IWbemClassObject *pClassObject = NULL;
# F4 M' {! [  U+ x; O- F2 `0 S* S  @  ULONG uCount = 1, uReturned; 0 h5 R3 Q4 x3 v* i% ~2 e5 |* @
  if(pEnumClassObject->Reset() == S_OK) / P: k7 l3 R$ F
  {   u1 P. n  n. i8 P" J! ?, `2 I1 K2 f
  int iEnumIdx = 0; 9 x0 T& T; b7 S$ X
  while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
+ i4 p+ o0 p( {2 o4 a1 s) c# u  {
$ p# ^8 o) |* c) P; L  lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");
4 `" f; w! I) H6 X+ v; _9 y  + \5 h* @: a: Q5 d& x/ u: }
  SAFEARRAY *pvNames = NULL;
( `8 T, `/ {- }) x  if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)
) U; w# L' J" V2 f* W! _- w, i  {
+ D1 S' R* l/ f# ~8 }: q  long vbl, vbu; & |# e$ B2 N3 d4 g( P" P
  SafeArrayGetLBound(pvNames, 1, &vbl); " {; x2 e) I# L! w
  SafeArrayGetUBound(pvNames, 1, &vbu);
' k. m& @. V# m& r: C  for(long idx=vbl; idx<=vbu; idx++)
% _7 a7 h# K, [9 q* W  {
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-18 08:54 , Processed in 0.020713 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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