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

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

[复制链接]
发表于 2006-4-16 18:40:38 | 显示全部楼层 |阅读模式
    一直以来都没有用过WMI, 都是用的PDH来获取系统信息.感觉两者很些相似,都是类似于性能数据库,基本的一些什么硬件软件信息都可以比较全面的获得.只是用VC来调用相对比较繁杂,用VB和C#就方便多了.这些天到MSDN上找了些资料,总算大致搞清了一些编程思路.对于那些很想知道怎么获取诸如CPUID,硬盘ID,BIOS信息以及主板信息的人来说应该有些帮助吧.试着用MSDN的例子乱写了一通,以下是通过WMI获取BIOS的例子,不对之处还请指正 ^_^:
+ o- j' o, S; W2 Z; E  --------------------------------------------------------------------------------- n( L4 k/ V+ X: e. o
  #define _WIN32_DCOM 7 I  ^# G) }5 |$ A. p
  #include <iostream> % ~5 }! {# e6 u  Y: O% S
  using namespace std ;
6 `; W4 b0 n( {/ s  #include <windows.h> 0 x% `- ?3 h. l" {6 A
  #include <comdef.h>
! S9 {9 @# n1 Y  #include <wbemcli.h>
% _4 ?! c/ N4 R  ' y. r- c; E. a+ O8 Y
  #pragma comment(lib, "Wbemuuid")
( `" Q) v, K) _6 M7 b  
% @. k+ ?  y  K1 i; v  G7 x  C  int main(int argc,char**argv)
9 B# S- M9 v( N* c; V1 U! P+ c. q  {
$ r' {" F$ l# V! w/ p  HRESULT hres ; 7 r, k* S1 `* d
  
9 B4 y& z" a2 y  // Initialize COM.
! l, Z# Y0 @0 C  hres=CoInitializeEx(0,COINIT_MULTITHREADED);
: I( M6 U3 e5 x7 _  j  if(FAILED(hres))
* M/ n# j) Z! O5 i7 t! F# b  { % Y. ?" J% y8 F% S1 q+ E: b1 R5 u, D
  cout<<"Failed to initialize COM library. Error code = 0x" % m2 D+ `5 A" N& O+ G0 c  Q
  <<hex<<hres<<endl ; 8 t: K1 v& m( {/ a* k' ~" \8 P
  return 1 ; # ~8 c: g9 C6 ]' Y* T4 ^- `( l
  // Program has failed. 6 w+ r6 v# q% K% y3 X: s) w4 H
  }
: D9 \- w( n" j1 `: J) I  1 P" Y/ n% N$ D$ }: q1 G6 `' h
  // Initialize
- f' ^5 G. q. {' Y  hres=CoInitializeSecurity(
$ D; Y$ s# \; q" l2 o  NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_DEFAULT,
" b0 c3 {" d* |# o5 J/ u  RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE,NULL); 4 F3 e; U: U! ]' }
  
4 C; i$ C3 U3 O( n  % j/ }' w- U' [) V
  if(FAILED(hres)) : L4 v; _9 D8 s# L  c8 y% c
  { . ?4 o+ d2 K- ?4 z! w- b2 r
  cout<<"Failed to initialize security. Error code = 0x" 1 M, |  X) j6 g! z0 p
  <<hex<<hres<<endl ; 1 u: m( \  R$ P
  CoUninitialize(); ( d8 [. x. S1 ^( G8 D  O
  return 1 ;
+ E# }: A6 t8 ^9 B% ?) I  // Program has failed.
5 p- w5 r+ R. }( W6 j  } ' T' e  r& A, O( u3 a0 }  L
  & H0 y! f; r7 S+ S
  // Obtain the initial locator to Windows Management on a particular host computer.
) E8 a9 j8 H" U- U9 ^  IWbemLocator*pLoc=0 ;
- M! H0 g% j" i$ ~  G) S6 u  
. g0 Z( D# X# @# ?" k3 n' R  hres=CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER,
0 y1 @. T+ L4 e  IID_IWbemLocator,(LPVOID*)&pLoc); * b. c# w, G4 k. c3 |/ E" v
  & Y" m# c4 o) o3 U) L; N) X. m& u
  if(FAILED(hres))
9 e' _4 {7 n, E3 u) L  w) m( `  {
$ u4 g! u* F- C' ~% g  cout<<"Failed to create IWbemLocator object. Err code = 0x" 1 f" B. y& k9 A! Y  e- S& y- j3 Q: Z$ A
  <<hex<<hres<<endl ;
5 S, G! _+ S, i  CoUninitialize();
* l+ X$ I9 ~) A  U2 N$ N4 k  return 1 ; ! B' Z6 h3 {7 ~1 V# {- N
  // Program has failed. ' N2 J8 M8 E1 J- @/ R, U1 N6 ]
  }
) r0 \/ U- H& [" h/ p0 J  
% M8 a7 U0 h1 L% g. `+ N8 V  IWbemServices*pSvc=0 ;
$ _) h+ u, c/ k. V. V# o  
; @2 P0 N+ w- n! D# k2 |# L7 x  // Connect to the rootcimv2 namespace with the current user and obtain pointer pSvc
# \- c* i  l( [/ c6 F  // to make IWbemServices calls.
$ q. P8 W  F- |: w  
; q( S$ s6 K3 l  k5 K6 H  hres=pLoc->ConnectServer(_bstr_t(L"ROOT\CIMV2"),
) b; E7 v/ u! k( X( l" P3 z( u4 g  NULL,NULL,0,NULL,0,0,&pSvc); 1 H, y, v! Q3 z. I* D9 i
  
' f, I. w9 H- i  if(FAILED(hres)) 7 c  B9 h2 u7 S
  { ( H! X4 W3 r3 g8 @( r& x
  cout<<"Could not connect. Error code = 0x" - P( N! ^( g9 H8 r; N6 y( k
  <<hex<<hres<<endl ; 9 g; T/ E2 P  Z0 G* n
  pLoc->Release(); ( ~  v* Y2 j2 c( l2 o
  CoUninitialize(); 9 L& H- `8 A- r4 L2 O8 j
  return 1 ;
6 M. Z- a, H4 i$ i9 \& ]2 V; W  // Program has failed. ' ?$ B8 j& x6 A. s; @( T
  }
* G; x4 K1 t1 S  0 \; w: v8 ^- A6 P
  cout<<"Connected to WMI"<<endl ;
2 j) e, b- r* D  _, S  
2 m3 z( h1 ^; x3 Q. T4 f  // Set the IWbemServices proxy so that impersonation of the user (client) occurs.
  s0 b% I8 j. ~  hres=CoSetProxyBlanket(pSvc,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,NULL, ( k$ D# m5 ]  G+ n
  RPC_C_AUTHN_LEVEL_CALL,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE); 1 V# g' ~8 N7 y1 a( B: ^
  
: k1 j' D# a7 w) x  if(FAILED(hres))
% Q7 I4 w3 g' [- J0 _  {
- W+ t7 c  B' v  cout<<"Could not set proxy blanket. Error code = 0x" . w6 Q1 V/ v, X% o+ D7 D, _- `% t
  <<hex<<hres<<endl ;
0 O) m  @4 H) [% Y  pSvc->Release(); 1 _0 }  ]/ T) Q9 l; I% P
  pLoc->Release();
- h% H9 P  g8 p1 y  CoUninitialize();
6 T+ h3 T# }2 @2 \1 V3 A  return 1 ;
; v; u3 x/ K# p) X; E) I5 D  // Program has failed. $ l: F% n0 r* X- Y. P- f
  }
# r+ X& Z+ G4 q/ n( h  ; W6 G; N5 G. B. M
  * T/ }7 B4 @/ v, S) Q. a1 y) }; O
  // Use the IWbemServices pointer to make requests of WMI.
0 I* {9 s6 K4 V) [) l  // Make requests here:
* j8 C1 S7 [! |; ]+ P4 D, v0 i  
5 j* ~5 N1 W7 v/ T/ X  // For example, query for print queues that have more than 10 jobs
' H2 j2 g) [. L8 X  IEnumWbemClassObject*pEnumerator=NULL ;
: H! ?/ r' ^5 {  p  hres=pSvc->ExecQuery(
0 r4 O) V& [8 P1 y9 X/ F  Y  bstr_t("WQL"), . h; e% s$ i& u
  bstr_t("SELECT * from Win32_BIOS"),
6 W& Z0 h$ s- Z9 u! g. U  WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY, , K  F2 t- Y* A2 b* s
  NULL,
, ^. o; ?+ f9 ~  &pEnumerator);   ]' D( B9 c& Z
  8 ?1 H$ l; c3 E
  if(FAILED(hres)) : z8 x, t2 @" t1 t  q3 O* Q
  { 3 _, v; A$ S) i0 t
  cout<<"Query for print queues failed. Error code = 0x"
) L3 N% L* q1 |" H  <<hex<<hres<<endl ; ! j9 H& S2 G/ S8 k2 q/ i& @: {) S
  pSvc->Release(); 2 a2 ^$ t0 b$ y% T7 g% d
  pLoc->Release();
+ x: \+ x" D% `; k) Z; ^+ j; Z$ X  CoUninitialize(); & Y' ]$ H1 F6 I' q! c  }
  return 1 ;
9 Y% G4 Y1 r5 U( ]* ]  // Program has failed. 4 K6 u! w* B/ ~  j' `; G
  }
! P) |& T  I) L, Y. I% K) `" }  else
2 s8 V2 f. c" q: `* l8 D, L& [  {
" h8 \' {6 Y2 y2 ]( ?* ^3 W" B) X  IWbemClassObject*pInstance=NULL ;
! R! S1 p6 _0 J) h/ i  ULONG dwCount ;
; Z$ P2 n( p6 f( q, @% }. I8 d  while(pEnumerator->Next( 5 H+ w+ t0 q$ P, d) A
  WBEM_INFINITE, : g& r. \  y7 A0 ^
  1,
7 w. Y' N# i" `  A) k$ l- r  &pInstance, & h6 _5 u6 o- |: O5 {+ z/ E2 w
  &dwCount)==S_OK) ! D$ ?( j# B2 P& b, I  {* W
  { 7 f1 F! L$ F) c# h. C3 ?
  SAFEARRAY*pvNames=NULL ;
* f: Y( g: C# k: G  m  if(pInstance->GetNames(NULL,WBEM_FLAG_ALWAYS|WBEM_MASK_CONDITION_ORIGIN,NULL,&pvNames)==S_OK)
$ u8 v- g6 f) Y' N" _: i  { 0 k: F  J. b1 v$ t3 z' }  `
  long vbl,vbu ; ( Q: K/ ?0 v1 \- e
  SafeArrayGetLBound(pvNames,1,&vbl);
0 j) H, B6 ]; @4 B- D6 r  SafeArrayGetUBound(pvNames,1,&vbu); ' u% o* i0 i) ^' {' @6 N
  for(long idx=vbl;idx<=vbu;idx++)
# I( t- g9 `4 g" T8 w: x  {
# s" [1 r8 k$ }0 p) @  long aidx=idx ; " V7 O0 W8 B% N3 o
  wchar_t *wsName=0 ; / i$ L8 P) y8 w# I, Q
  VARIANT vValue ;
/ D4 k* Q4 J7 {- ^' U3 ]  VariantInit(&vValue);
6 G0 D! N5 R8 ~4 I  - X( O! \; M3 @5 J
  SafeArrayGetElement(pvNames,&aidx,&wsName); 6 M( }; Q, e; Y" T
  " J0 d$ ~& |! t. G$ I2 ^3 q: N8 F0 [
  BSTR bs=SysAllocString(wsName); 2 L: @. M& p( L$ T2 [
  hres=pInstance->Get(bs,0,&vValue,NULL,0);
: v) Z% ?: Y8 p3 b& `7 R* J  SysFreeString(bs); & f1 t0 b9 q2 c7 M) a' x6 L$ X) L
  
8 }* ?: x0 K' Q9 _  " v+ ^* c* F! c& J0 B+ W4 {! _$ o' d2 e
  if(SUCCEEDED(hres)) ) @) E  q" g4 @7 O& Y
  {   G  b/ K; h  `4 l- D3 g0 U# `
  char szANSIString[MAX_PATH];
; i  f' ~! {, h' n3 I  L$ R  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,wsName,-1,
- s# \( K6 K" `+ W7 X$ g  szANSIString,sizeof(szANSIString),NULL,NULL); : ?- E, {  E( ?) q+ Q, C
  / Q- j6 x$ d- `/ g. Y4 P
  cout<<szANSIString<<" : " ; / ?2 i" [) |6 X
  switch(vValue.vt)
, B# |5 b# c! P1 j6 G  { 7 o9 b, B  l: m  G
  case VT_BSTR :
( E7 [$ B  d# [) @# t  wprintf(L"%s",V_BSTR(&vValue));
: ]+ \* d3 `4 [7 j+ c! V* `% h8 P  break ;
- d; I! f; x8 g4 ^& I  case VT_I2 :
9 [! s( a/ L& `  wprintf(L"%d",V_I2(&vValue)); % L! u, D; o, W. D/ [
  break ;
& u9 {, O' D- ?- q  case VT_I4 : . |) G, d9 V, |
  wprintf(L"%d",V_I4(&vValue));
+ v! N' }2 T. n. G  break ;
4 `2 U! |1 S1 z/ \  case VT_BOOL :
4 V, a4 s! }- S6 _  wprintf(L"%s",V_BOOL(&vValue)?L"TRUE""FALSE");
# a/ p' o4 v0 Y9 F+ k. _, I" {  break ;
3 P# ?8 H5 k, s6 M  L7 y7 s1 g  default:
: x9 p! w' l+ p( [$ |* i9 {  /*WCHAR tmp[100]; ; f5 \8 L6 N+ ?' O  n% k$ w9 _
  wcscpy(tmp, V_BSTR(&vValue)); , U, T' W( N! v+ h
  char tmp1[MAX_PATH];
( b% j, e) g  Q+ E2 _  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,tmp,-1,
: R+ d/ ?1 B& j) ^) u  tmp1,sizeof(tmp1),NULL,NULL);
% u% E: E8 u& D' }1 [5 d5 @  0 o% V7 t  f: Y3 c
  cout<<tmp1;*/ # ]7 e( \  F$ q1 N
  break;
3 @4 K% w5 L# A5 f  G1 d& _: m8 j6 L  } ! ~% E, Y. N1 i4 ?  V
  cout<<endl ;
+ I+ f' i) Q+ u) y5 I/ z$ A  }
( ?1 O$ v  s* m4 `* q. V  0 j" ?4 B. Z$ p
  SysFreeString(wsName);
) h. ~- g- b" e% J" X* W  } # _% i* ~! l1 D3 V( V
  4 f1 u5 F% k& ^+ y1 p3 f  [- q
  }
4 L0 ?1 b" ?0 q5 ~. |  else 3 ?8 s( o* W  M# C
  { , L' z1 A* d; i  b! ^$ v
  cout<<"Query for print queues failed. Error code = 0x"
* X! s8 S5 h; r- W7 }  <<hex<<hres<<endl ; % o7 m+ q) c6 |. l6 w
  pSvc->Release();
# I5 z; r3 {1 x) L% B  pLoc->Release(); % Y" v9 e* |* T
  CoUninitialize();
# ~0 p' u( O, ^; W4 S% w2 i  return 1 ; + _9 I5 C8 N% A* t) i3 C$ f
  // Program has failed. * D1 t2 n2 R2 f4 A+ K4 ]4 g  W
  }
, J8 B1 W1 |# u) K  if(pvNames)SafeArrayDestroy(pvNames); 7 |! T# D/ r8 K, ?, J
  } : F" L# W& d2 o' ~3 d$ G' k0 V
  if(pInstance)pInstance->Release(); 2 l8 [8 C, `, Q) n7 [+ L8 L
  " ^' M" D4 C: M) |' G0 O% ]
  }
2 A0 A! Q( _& e, o5 Y  // Cleanup
# H: `- D' d( t* [  z2 w; p! |  B2 n  // ========
: x) G: D7 u1 ?8 }6 ?  pEnumerator->Release();
! o8 y( B7 M8 T  b! t  pSvc->Release();
7 A$ i, a' G) x9 y  pLoc->Release(); ! e( ?: y" _/ H
  CoUninitialize(); % W! H2 S3 T/ ?( |
  
- I6 i( l5 I) {% I. n' B0 s  return 0;
/ u, m+ @) p: Q- C  // Program successfully completed.
2 T: W- t& \8 \2 N1 e: g; z. p  }
$ ^9 c9 Z) S1 U  //-----------------------------------
3 ?( W: q% M* ?$ ?1 T$ B  
4 b$ n$ P3 F5 _, |8 b  对于怎么用BCB编, 感觉还容易一点,因为我在类型转换的时候碰到了一些问题,而在BCB中的Variant类做了比较好的封装, 具体代码可以 http://www.cppfans.com上找到.
( @0 l0 R; ~$ }+ E8 ?; J- z) c8 \  
. M; A8 s# H7 M2 ]0 B+ [  void GetWmiInfo(TStrings *lpList, WideString wsClass) 9 p2 \4 x2 D2 [6 ]. \3 I4 x0 N- P1 E
  { * h1 Z6 O6 y7 V2 N/ F, @- |
  IWbemLocator *pWbemLocator = NULL; 3 Z, I0 W/ [, Z. _$ @
  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK) - G4 D, b  l* {7 y* p" T
  { ) H% J; W" @. n8 E0 m$ K8 a
  IWbemServices *pWbemServices = NULL; % ?. a/ r/ M1 d  ?. H
  WideString wsNamespace = (L"root\cimv2");
5 U$ Q. E$ T( D( p# s  if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)
' C  P! i) J1 r( }! W# c; o" u  {
7 e2 x! ~* s2 o5 X( Z8 y  IEnumWbemClassObject *pEnumClassObject = NULL;
. D0 l% z% C+ Z: C8 S9 i  L# t  WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;
1 Q/ |  q, s- Z8 q3 B/ e( d0 S) d  if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK) $ {# A: Q7 X0 l8 a0 e* L
  {
/ a9 d8 _' b9 q* |  IWbemClassObject *pClassObject = NULL;
8 d. S) s! y8 E/ a, L2 }$ h0 g  ULONG uCount = 1, uReturned; , z0 y8 r: N) v) P; W) b
  if(pEnumClassObject->Reset() == S_OK)
: ~7 e, S. k/ m' O& D- m+ u  {
1 S4 ^9 Q. L7 p! o% Z& z  int iEnumIdx = 0; 5 T. T( m  D! K! Z' E) O
  while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK) / H$ I9 H8 G+ o1 Y
  { 9 _, g1 b' |: l
  lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------"); 6 ?! p- A" C; e8 H
  9 c+ t7 ^3 P) A- z! n
  SAFEARRAY *pvNames = NULL;
: |0 ~6 x# \& ?; m  ~0 W$ o* J' O  if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK) 5 r% j" W3 r' p6 Z* s
  { 5 I) x- N" u) M) k
  long vbl, vbu; ; ]8 j/ A$ a/ n' t  i
  SafeArrayGetLBound(pvNames, 1, &vbl); 3 R& K  U5 ?9 v* [. K/ A
  SafeArrayGetUBound(pvNames, 1, &vbu);
& J0 @' r8 L: x' ^5 g  for(long idx=vbl; idx<=vbu; idx++) 4 B8 M% ]0 S; ]/ e$ L
  {
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-8-9 01:43 , Processed in 0.035072 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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