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

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

[复制链接]
发表于 2006-4-16 18:40:38 | 显示全部楼层 |阅读模式
    一直以来都没有用过WMI, 都是用的PDH来获取系统信息.感觉两者很些相似,都是类似于性能数据库,基本的一些什么硬件软件信息都可以比较全面的获得.只是用VC来调用相对比较繁杂,用VB和C#就方便多了.这些天到MSDN上找了些资料,总算大致搞清了一些编程思路.对于那些很想知道怎么获取诸如CPUID,硬盘ID,BIOS信息以及主板信息的人来说应该有些帮助吧.试着用MSDN的例子乱写了一通,以下是通过WMI获取BIOS的例子,不对之处还请指正 ^_^: 6 a4 W5 I7 \, [$ U- r- ]
  --------------------------------------------------------------------------------/ W( k# ?8 i" C$ y, O5 f3 x7 j
  #define _WIN32_DCOM ! I- v& c3 l) s$ q/ [4 \1 Y
  #include <iostream>
) o# i" z2 [5 d$ w! F/ C; {+ @+ U: O/ W  using namespace std ; : V+ L5 ~2 |8 X) K$ s
  #include <windows.h> 7 I6 Q, ^6 j5 L$ O" J
  #include <comdef.h> ; A2 B% p+ \" _
  #include <wbemcli.h> # n: X$ M' y3 d
  ' i9 O. r7 s  p3 l' L
  #pragma comment(lib, "Wbemuuid")
; U  ~* [# b0 S1 ]6 V  
6 B% B9 z3 z( X2 x$ i. y2 h  int main(int argc,char**argv)
; ?# v3 i2 g/ g  {
- [& n7 I& h: p" d  HRESULT hres ; # U! J9 p# y; z' r
  4 U" N0 e! o& ~
  // Initialize COM.
) i/ k/ H, Q3 o6 s. p6 h) ]* V  hres=CoInitializeEx(0,COINIT_MULTITHREADED);
- a, H# F% k) S2 J3 Y. ^# z0 b  if(FAILED(hres)) 8 K2 X* U0 H- L. i
  { : [7 p4 p/ I0 ^2 y: ~3 E# q* w
  cout<<"Failed to initialize COM library. Error code = 0x"
) ^% R% r5 ]4 f/ n/ i1 J: ^; P# P  h  <<hex<<hres<<endl ;
" y( h# z1 V! `  return 1 ;
% c+ i, ^! C% O' J  E1 i' T( g  // Program has failed.
0 X3 j- x& c- L  p  } 6 s5 i* Y2 y8 d% u
  
; G" N$ H# ]5 H  u" |. T4 X' T  // Initialize
3 X+ [2 G( z9 D* ?: _; @8 l. Q  hres=CoInitializeSecurity( 2 p# q0 g: D6 n
  NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_DEFAULT, . @: |, r, N. e! N8 x/ r0 S0 I
  RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE,NULL);
: s8 S4 H. |" }5 m  , f. Q8 L% \& m" C- O: a+ F
  
- r# {  }) ?* j& K$ j" Y# U  if(FAILED(hres))
: y: A1 p5 S  [. d/ _  {
. M/ E2 ~) Z, \( b* u) E6 b  cout<<"Failed to initialize security. Error code = 0x" ( |, ?# E6 z3 E: t8 ?6 \
  <<hex<<hres<<endl ; & ?+ r0 u" [2 |3 h1 r: t1 S' k6 }
  CoUninitialize();
- S0 l- z* ^: i- Z  y  return 1 ; * x4 g( X: U8 U( S# I
  // Program has failed.
# `+ A0 D$ a& ?. @7 Q  } 2 R; P8 b0 C, |
  ; @) D* M: M$ @2 m( S
  // Obtain the initial locator to Windows Management on a particular host computer.
4 {) y# `6 d! O$ ], Q  IWbemLocator*pLoc=0 ;
$ C, N9 x  B0 A3 e/ G2 A" m  . S, ~, i! j- d2 U: `7 N" g
  hres=CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER,
6 I8 |0 U+ ?) {- h/ t4 p  IID_IWbemLocator,(LPVOID*)&pLoc); , p; O8 b- k, Y5 J% T/ p' K7 m! {- ]
  6 e1 K" a3 f4 C: U! ?( N3 l3 N" Q
  if(FAILED(hres)) + H/ i- \2 Y$ E; M1 m* ?+ o
  { 9 A! L) C" |; g+ T$ t, Q4 K7 O0 f- I
  cout<<"Failed to create IWbemLocator object. Err code = 0x" ) J$ ?6 O2 D# O
  <<hex<<hres<<endl ;
8 _/ f7 }% \9 S* K  CoUninitialize(); 2 b, m( U4 j) ^7 A
  return 1 ; 5 j/ e! [3 v: _
  // Program has failed. 7 f' p* U" M9 O: @# e; B% V
  }
7 z: H% x" Z: {# V& l" c$ F3 a  
+ w+ u- J7 Q+ j2 h& Q  IWbemServices*pSvc=0 ; 9 q7 p% b. ]: t9 f
  ) [* U; U2 @1 X
  // Connect to the rootcimv2 namespace with the current user and obtain pointer pSvc
/ X6 P! ~# G0 h; x2 z  // to make IWbemServices calls.
& i) ]1 M9 }" d" N1 E: p( l  
: E" o8 l# P5 q2 G: [  hres=pLoc->ConnectServer(_bstr_t(L"ROOT\CIMV2"),
9 C" O- z/ o7 o( D5 j, Q  NULL,NULL,0,NULL,0,0,&pSvc);
: r/ s/ }$ Y  G0 Z7 \$ o, m  
: F4 F# w9 q. u6 f  if(FAILED(hres))
+ J1 s. U, |$ h& V5 }8 ?  {
2 e) T9 r8 b- Q! O4 ]  cout<<"Could not connect. Error code = 0x" ( [3 W# c" }$ u% G' O1 t3 K
  <<hex<<hres<<endl ;
  _3 y1 P+ l7 \9 m  pLoc->Release(); + P1 w& W' r; e2 i* ~9 ]
  CoUninitialize();   \3 I6 ]  w" E* J. E: a1 E. ?8 q
  return 1 ;
( i) |# v& L. x9 @1 v* A  // Program has failed.
4 t" m! z# H1 L( T  } 4 w  Y' a* X+ q0 z2 \
  
/ h9 J3 t- M* U, |2 [  cout<<"Connected to WMI"<<endl ; + E; ]3 c5 T: c0 F: @9 q) A+ T
  
) F  ^+ T/ m' E' X& |3 J. k( g/ Q6 \  // Set the IWbemServices proxy so that impersonation of the user (client) occurs. : p7 X' f2 Y" d' [; [
  hres=CoSetProxyBlanket(pSvc,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,NULL, ( ]) A4 \/ U: X9 X
  RPC_C_AUTHN_LEVEL_CALL,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE);
3 |  u; i( Z( O0 q2 n% p  + y# n/ n) |# F+ {- Q9 ]8 {$ m% a
  if(FAILED(hres))
1 J! q& _3 x" @9 s/ f& v- Z2 q  `4 v  { / j2 V" \$ K5 h; z, K; _: {
  cout<<"Could not set proxy blanket. Error code = 0x" 9 c/ _, y6 D- d& e1 k1 H
  <<hex<<hres<<endl ; 8 C$ @% o- w1 r8 d: E
  pSvc->Release(); . P' ~/ c2 q* A
  pLoc->Release(); $ u7 p! Q3 N+ q
  CoUninitialize();
/ k9 _; O6 u. `: j" f( s2 u  return 1 ; 9 B# f& @; S/ _6 A( z
  // Program has failed.
4 H/ u: g( q& s$ z6 g! V& I1 i  }
$ m& t3 k) z. g! m- f  
( V! T; {6 O/ y/ G  3 @# |. M  N; p- ]3 S+ }& V4 d8 Z
  // Use the IWbemServices pointer to make requests of WMI. # C+ T2 t/ W# g
  // Make requests here: ( ?. i% M2 L& g! r4 _1 g3 s
  
* V; I7 @# q: I+ o. `! t  // For example, query for print queues that have more than 10 jobs ( h4 y& ?2 r: D) N
  IEnumWbemClassObject*pEnumerator=NULL ; # {1 h( T4 n5 b4 H: W3 ?) F- m0 G
  hres=pSvc->ExecQuery(
' t% m) I0 H4 C5 v& b/ J7 j2 _  bstr_t("WQL"),
, ~. O8 P. Q1 E/ ]  bstr_t("SELECT * from Win32_BIOS"),
3 M2 t; s) C0 n( y4 k: V5 A. W9 r  WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,
9 k6 e; k4 _8 I  NULL,
3 ]' n$ L9 _6 h9 W  &pEnumerator); 4 H% n# k. {. h# B
  
+ e/ T* B) i' U3 G; n2 {8 |  if(FAILED(hres)) 8 s' ?" F7 _0 o  o
  { / X* D1 O: L5 }5 |7 W4 W0 J* p
  cout<<"Query for print queues failed. Error code = 0x"
. e! P3 T; t! h5 U/ c+ d7 N) L8 T3 m1 S" p  <<hex<<hres<<endl ; / _' ~" b5 y3 K  ]
  pSvc->Release();
4 q) n& n# J9 ?  }0 }. W9 L9 k  pLoc->Release(); 2 `9 X3 \0 u# x3 }$ M- [- M
  CoUninitialize(); 0 j( O4 }5 g" W- H2 Y" ]
  return 1 ; # U3 h. ?- w, J/ w3 l% X- u
  // Program has failed. * G, g% n! k/ M9 [3 l3 e
  } + [2 |5 {" r2 n1 |
  else , C5 G0 g1 \4 S% f4 {3 [, l
  {
/ f6 X6 y, F" M. k- \) ^. h% L  IWbemClassObject*pInstance=NULL ;   x7 j9 ?7 @5 o0 `: N
  ULONG dwCount ;
% x: P0 O% J9 T& n5 J7 x  g/ L  while(pEnumerator->Next(
) _8 {+ W) t! P; |( t0 m  WBEM_INFINITE, / U* h- O4 H2 i8 o7 P) W7 f% |
  1,   t: X. h' ^& A( `: Y
  &pInstance, ( E8 H' e: D" L, ~( y
  &dwCount)==S_OK)
9 v* G# e( f* y% U' e7 s  { ! [: S$ V7 `, h
  SAFEARRAY*pvNames=NULL ; # H) f* i# n7 p- _' b& k! }+ \
  if(pInstance->GetNames(NULL,WBEM_FLAG_ALWAYS|WBEM_MASK_CONDITION_ORIGIN,NULL,&pvNames)==S_OK) , j6 ~1 A& {: |
  { 2 w. I* [" ]$ W2 i8 g) K" H/ V
  long vbl,vbu ;
# t0 q! x. v6 H! D  SafeArrayGetLBound(pvNames,1,&vbl);
; v6 a+ P# w; K6 n2 |9 f1 F3 Y  SafeArrayGetUBound(pvNames,1,&vbu);
# S1 f$ Y$ L/ m$ [4 J3 c" d6 I  for(long idx=vbl;idx<=vbu;idx++)
6 f% ~- i0 C+ g  V: C: K  {
% |- g7 p) Y9 e  long aidx=idx ; 2 \. z" B  `+ k% P4 t  X5 w
  wchar_t *wsName=0 ;
( R0 ~1 F. a7 N0 V  VARIANT vValue ;
1 r1 L  G: h* u6 Z  VariantInit(&vValue); . c9 b4 T7 t: _
  
! m& ?1 H* j# _, j- t  SafeArrayGetElement(pvNames,&aidx,&wsName);   Q2 j( ?! {- q4 z# d
  1 W! R6 ?3 p/ S; D; X
  BSTR bs=SysAllocString(wsName); : B( o% `4 P' C2 o3 _- l
  hres=pInstance->Get(bs,0,&vValue,NULL,0); 7 i: h' A0 w6 q( M, m/ M9 o
  SysFreeString(bs);
. Z2 d5 {2 s1 v% ?" H  1 b6 a5 f7 l  l9 I4 _
  
& y" C- n2 l* u4 Y- V  if(SUCCEEDED(hres))
  w) q! p* w, J+ [! X# P  { - ?+ l; x& d* U" T( s
  char szANSIString[MAX_PATH];
( N% C' A% |/ K  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,wsName,-1,
$ c- ~' `' q) K9 _1 o. r  szANSIString,sizeof(szANSIString),NULL,NULL); , I* k( _& k) Y5 D* g/ H2 U4 ]
  : B7 o4 ]% N9 |5 o6 L6 s0 Q
  cout<<szANSIString<<" : " ; # W, @7 h5 L; N6 b# [$ S5 Y3 u
  switch(vValue.vt) 7 Z% S$ R3 X  p: y  h( O
  { & n2 l$ r4 `% k* _
  case VT_BSTR :
2 |& W. o" y% P& Q9 J9 t  wprintf(L"%s",V_BSTR(&vValue)); 5 c! }( g) ]7 ]% E9 f. [8 H3 V
  break ; * u3 B& g! r$ F2 h
  case VT_I2 :
* F7 k8 D3 N* _1 _6 x  wprintf(L"%d",V_I2(&vValue)); : D3 m) b; d# i9 _4 m1 e% x
  break ;
+ H; S  W9 j% a7 A6 o8 p" p  case VT_I4 : ! ~" {. G$ C/ G0 l' \+ \
  wprintf(L"%d",V_I4(&vValue));
; v6 K3 L2 f# m# Q% l( U  break ;
' }8 G- A9 b- z8 S  case VT_BOOL : $ v/ C% P! F/ G( n8 c( W
  wprintf(L"%s",V_BOOL(&vValue)?L"TRUE""FALSE");
" m8 b7 p+ `- W2 N' t! q* p  break ; , E& C, d5 G$ O+ Q5 {* P: `4 J
  default:
3 ~, {; G! T& C8 ?4 Y  /*WCHAR tmp[100]; 7 l6 ]% N) `1 U# c2 W. k
  wcscpy(tmp, V_BSTR(&vValue)); 7 K3 E: ~. U: [! y
  char tmp1[MAX_PATH]; ( _* q! `6 T- E9 h4 N
  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,tmp,-1, ; F  ?' }9 P' y; g
  tmp1,sizeof(tmp1),NULL,NULL); ) M# ]7 o% {8 _. O; |5 A0 _
  " m& O1 x* h/ H& j
  cout<<tmp1;*/
# y* J( I: C9 y. Y7 O# A% R" e  break; & p( y( a* k  y8 [% V4 L
  }
9 I3 D$ o; W6 g: @2 b  cout<<endl ;
2 h( q- e8 W) y  }
( G; u8 }9 S4 ^+ I# E% e  
, t2 n2 a1 b  h1 ]  SysFreeString(wsName);
& c' I8 {0 }' H: _/ P/ L  }
8 j. ?3 M$ A4 Y. }  
  L3 ~! G0 O( c" `. `! T, K  } ) n: ?  H$ n% D* g- G; V; x
  else % [) A% I- q/ l  D/ R8 h0 ?
  { * ?/ ], ]# w3 G
  cout<<"Query for print queues failed. Error code = 0x" 1 Z1 l* ~( T1 \$ F; A. h/ i
  <<hex<<hres<<endl ;
6 v* n7 S2 e) ?- @% D  p  pSvc->Release();
& Y2 W4 K% ~# f! ^2 H  pLoc->Release();
; R+ i# M8 K. \) k7 ]7 \3 F  CoUninitialize(); 9 w+ f4 b- w3 p$ t1 n; Z
  return 1 ;
( U% p6 A$ V+ x3 A1 I  // Program has failed. ' k7 `3 [/ r$ {, E) _
  }
% V  p2 ]* @) B3 r  if(pvNames)SafeArrayDestroy(pvNames);
( G: T: f  F1 V/ o" s  }
+ r: G/ a7 X, G, c/ X. `  if(pInstance)pInstance->Release(); 8 I) i# k9 n+ T2 W8 L& x( F
  
( Y: p* `, o2 H, p( ?" l8 ]# j, O  } ; B5 j" X: F  Y; r  P' A! ?0 b& Q' ]! Z9 p8 a
  // Cleanup $ M1 D) Y. h$ j
  // ========
1 A1 }8 N: P( d$ A  pEnumerator->Release(); - p* e# y; H# [
  pSvc->Release();
( z* O' m2 C2 o2 F) {  pLoc->Release();
: i8 ~5 \6 E2 H  S, x5 A& n! H  CoUninitialize();
/ O  i  M. p* f; |: `  
2 E. N0 N6 w' [/ [* r0 }+ \  return 0;   H, A8 p$ b! \
  // Program successfully completed.   H2 w$ h3 C% D6 e
  } 4 e1 O9 C: [3 ]8 {, j
  //-----------------------------------
  t) }* g( E; d2 H) Q9 j2 j  % p' Z  t1 w% B( ]/ ?7 x# n
  对于怎么用BCB编, 感觉还容易一点,因为我在类型转换的时候碰到了一些问题,而在BCB中的Variant类做了比较好的封装, 具体代码可以 http://www.cppfans.com上找到. 7 d8 L' a: w6 D. E) P) R
  
) y* V2 d! ~- n$ d1 y  void GetWmiInfo(TStrings *lpList, WideString wsClass)
" _# y. ?/ n1 _# F  {
) \5 q# l5 G# F- }) `2 f  IWbemLocator *pWbemLocator = NULL; . T9 N8 E' r: `0 B% I# p$ i, u. m
  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)
9 \; M% c2 f; u" y; x  {
- q* u; [' ?( E" N  s, H6 B. Q. m. u9 F  IWbemServices *pWbemServices = NULL; . W& x0 I& b. ^* J3 a' Z2 _
  WideString wsNamespace = (L"root\cimv2"); - B" O% d$ w9 H. ~
  if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK) / O% ^* Z& o3 h) k
  { ; I6 P3 U+ ]" Z! f' s, z" R5 y2 Q
  IEnumWbemClassObject *pEnumClassObject = NULL;
! C$ l( S  T' g# |9 e6 G, Z+ h  WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;
) B7 {4 S9 F- m% g6 r# @  if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)
; L$ O* g9 X# x( [4 w3 F  { / a! T; ^3 _) ~' g# }
  IWbemClassObject *pClassObject = NULL; ( a7 {/ F& `( P
  ULONG uCount = 1, uReturned; , C( D1 W; J5 V) Q. ]
  if(pEnumClassObject->Reset() == S_OK) , A) g6 R+ _$ e% w
  { ( I* z2 _+ G2 t" e: ^5 s7 h/ W
  int iEnumIdx = 0;
0 A; A0 l  W" V( ^  while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK) 2 P2 Y7 `: |9 ]. F% u7 G7 d8 X* X
  { 8 g# |" q$ O( A* r
  lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");
" E& y% f  n9 T5 t  5 B6 j2 _$ \- I& S  G, c) ^
  SAFEARRAY *pvNames = NULL;
% j9 C1 w* k1 h$ I( ?# y( G8 b; V! u  if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK) 8 V0 L' q  t" p, x4 I  q
  {
. \+ @# G" t, r3 ~9 {  long vbl, vbu;
' B; N+ U, Z" G/ z* p  SafeArrayGetLBound(pvNames, 1, &vbl); # p# \& ]3 f5 M$ p% A
  SafeArrayGetUBound(pvNames, 1, &vbu); 1 t, U5 o: |# [* O
  for(long idx=vbl; idx<=vbu; idx++) + j% C0 }- Z% I" {, a
  {
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-5-5 04:50 , Processed in 0.014716 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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