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

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

[复制链接]
发表于 2006-4-16 18:40:38 | 显示全部楼层 |阅读模式
    一直以来都没有用过WMI, 都是用的PDH来获取系统信息.感觉两者很些相似,都是类似于性能数据库,基本的一些什么硬件软件信息都可以比较全面的获得.只是用VC来调用相对比较繁杂,用VB和C#就方便多了.这些天到MSDN上找了些资料,总算大致搞清了一些编程思路.对于那些很想知道怎么获取诸如CPUID,硬盘ID,BIOS信息以及主板信息的人来说应该有些帮助吧.试着用MSDN的例子乱写了一通,以下是通过WMI获取BIOS的例子,不对之处还请指正 ^_^:
# P. M, k  l# N$ E  --------------------------------------------------------------------------------4 g5 O" ~7 N+ a. y
  #define _WIN32_DCOM
( l# _$ |6 U5 @" o3 |  #include <iostream> 5 E$ A: i; f* c! M6 n# P
  using namespace std ;   x  T: P7 |1 H+ S% {
  #include <windows.h> 4 p" R/ U" S& l: f. ~/ u
  #include <comdef.h>
: ?' I5 D% W( Q% a1 k  #include <wbemcli.h> , K* I3 U! [; C: @& A
  # |- `( |; O* t( @9 Q+ z& a5 e0 Y6 X
  #pragma comment(lib, "Wbemuuid") ! A9 G: V8 v, Y! w2 G5 h# ?/ J
  
" |# e6 P$ M) U4 \# X+ g' w2 R  int main(int argc,char**argv)
* y  ^- }/ K* c% a# v8 P3 n. t  {
3 {8 f5 x8 Z: O  F7 C; Y" Q( l* s  HRESULT hres ;
, R6 q- L3 d# x( B% ~  
- t& y9 G) C2 X) S& a. L  // Initialize COM. 5 M/ T! g( Y! q9 J" c
  hres=CoInitializeEx(0,COINIT_MULTITHREADED); " Z! j) t$ v" U( t2 P$ I. H: z
  if(FAILED(hres))
( P, ~7 {/ I. |6 O& M4 ~  {
/ X1 w- H  n1 U  cout<<"Failed to initialize COM library. Error code = 0x"
7 l- f9 j6 U$ h% r. P+ f3 Z; m  <<hex<<hres<<endl ; : ~+ R6 v. {1 G7 A9 v. {
  return 1 ; ( Q; M. Q! T7 }) n) I0 y
  // Program has failed. * p* m, S2 L% \7 S& u8 F
  } % @/ o" q9 Q+ K) M7 z% X$ `" V" M
  
9 I& P0 _. \" L& r/ G9 k  // Initialize " B+ D  Q  ?& n; F
  hres=CoInitializeSecurity(
( k8 {& o5 n3 @8 m4 j! Y, h" Q- u  NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_DEFAULT, + P) v5 f5 V5 W" _$ w
  RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE,NULL);
. T+ h0 o' M8 ?+ |2 [; F  / O* D; x( K0 A# ~# s
  
. i0 e6 e4 ^& l4 z7 s) l7 a: r  if(FAILED(hres)) " _/ F0 O. u3 T+ W, Z7 u+ ?" @
  { 8 @6 O% M( B3 Y' C
  cout<<"Failed to initialize security. Error code = 0x"
5 H1 g+ v5 U  W# E  <<hex<<hres<<endl ;
. |+ |* _# ]" X9 t1 y! B0 ^  CoUninitialize();
8 _8 H* h# h$ p6 w  return 1 ;
$ `: E2 Q, F6 b& g9 f2 F! s  // Program has failed.
, t# H; A, S' U" W* T$ @$ j; [  }
9 u  A# W% o5 `  ! X2 U1 J" L, M5 S$ O! m" v
  // Obtain the initial locator to Windows Management on a particular host computer. + c) S" g$ b1 K: t4 R
  IWbemLocator*pLoc=0 ;
# c3 U1 h- t  x5 S3 W! a% j  : K4 u0 p) L5 ?3 {" R
  hres=CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER, % p7 B8 [% T  P. z
  IID_IWbemLocator,(LPVOID*)&pLoc);
+ _4 h, Q! ^- x4 ?, T" A1 f  
7 W; p" z3 s% c% s  if(FAILED(hres)) 1 U2 M* V3 ^) y! O
  {
' V0 g" |7 `0 S' g  cout<<"Failed to create IWbemLocator object. Err code = 0x"
4 R' l) {1 h. E6 ~  <<hex<<hres<<endl ; 3 r8 C2 c) D8 D5 A& G5 K* s: {! ~
  CoUninitialize(); " n  E( ]: k5 ?2 ]$ }
  return 1 ;
" ~) \9 J* H- ~- S1 c  // Program has failed. : R) d& W; G5 q0 C
  }
! y% G5 q2 g6 @! P2 C, P  
; l0 y7 F5 ]; _$ E* t# \7 Q2 s; l  IWbemServices*pSvc=0 ;
) N/ n; q! j) ^  % @, F3 J1 d$ W! |( e
  // Connect to the rootcimv2 namespace with the current user and obtain pointer pSvc
6 b* o% z- j) X# ~1 c# V  X3 z, u  // to make IWbemServices calls.
1 e" e; E6 {' X2 V  
3 i. ~( Y/ t. ]2 w) S  I- n  hres=pLoc->ConnectServer(_bstr_t(L"ROOT\CIMV2"), 7 N' M. Z4 F+ B" w9 v3 \
  NULL,NULL,0,NULL,0,0,&pSvc); 7 `5 q3 R3 P. S) s/ g  R& e
  
+ ^; Z4 c1 g) i8 o* {; Z  if(FAILED(hres))
/ ?/ K5 U' I1 d+ D# ?& Q  {
9 X& Z+ a; ^! V, Y% }# W7 B  cout<<"Could not connect. Error code = 0x"
1 C) l7 G9 [/ a8 s" Q7 d  <<hex<<hres<<endl ;
  t9 Y$ v1 z6 z; P  V9 @! f8 l  pLoc->Release();   L  G& H. l. o* ?
  CoUninitialize(); , v0 p& `0 V; z6 K
  return 1 ;
4 J8 V; v: e( V9 l; O  // Program has failed.
8 G" f; W3 M* s6 ]7 c4 M- j  } ) O, j. e; N* Z* K. u' i
  
2 i" t' h: p2 E0 O: v0 N3 b  cout<<"Connected to WMI"<<endl ;
9 @; W: ^; H8 n, y$ R3 J* m6 W# D! i  8 Y( a2 X# c6 h# @3 X
  // Set the IWbemServices proxy so that impersonation of the user (client) occurs. - E, x" Y& x3 Y) N
  hres=CoSetProxyBlanket(pSvc,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,NULL,
7 R  K" x6 v$ K  RPC_C_AUTHN_LEVEL_CALL,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE);
3 c  N: c2 {# J* |7 T0 o  / @; w8 }% b% N/ c8 B
  if(FAILED(hres))
; d6 k* H4 A2 P7 Z) D  {
( `/ ~8 C" b( |9 `1 |. S  cout<<"Could not set proxy blanket. Error code = 0x"
5 b! w; G3 X2 g' Q9 X  v. Z  <<hex<<hres<<endl ;
, J% S3 {3 y; y- t9 ]  pSvc->Release();
7 J) M- c+ w+ [  pLoc->Release();
7 P4 s5 F  B* T  o: `3 ?: {$ S  CoUninitialize();
4 }6 ]7 R# ?3 E% v/ v( ^) h  return 1 ; % e9 G0 ]6 T( A2 }
  // Program has failed.
/ U8 g6 m) U$ Y) t( w3 V  } . ]$ y9 o0 Q8 W
  7 Z# l/ f3 _# S: F0 a' o
  
/ N* q9 y+ _# |" `7 M  // Use the IWbemServices pointer to make requests of WMI.
, V. K/ r9 \! j- k5 |8 Z  // Make requests here:
# E6 P) c; \, D- X' [  ) {5 A$ N/ I; W, t' A: _$ Y: K4 r
  // For example, query for print queues that have more than 10 jobs ( L4 P3 R" q9 U7 c
  IEnumWbemClassObject*pEnumerator=NULL ; 5 Q& q' j9 q( P/ ^1 U; a' ?, a! x
  hres=pSvc->ExecQuery(
) b  z. ?! d* W) L. z3 B  bstr_t("WQL"), " R% g  p+ G. T
  bstr_t("SELECT * from Win32_BIOS"), 4 V  M# j' d# X  G3 n
  WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY, : F) n# u5 ^, f5 I- T
  NULL,
; W9 o6 P# H7 ^+ g  &pEnumerator);
1 A2 z4 n5 n9 j& U7 A4 m4 r  
) k( O' @( l4 \% b0 a: e5 k( z7 l  if(FAILED(hres)) : c0 P" P( s2 |+ v$ F
  {
. O& j& P/ t. y9 _  ~/ Y- _  cout<<"Query for print queues failed. Error code = 0x"
4 v) V8 s2 ~" W6 a) z  T# o, }  <<hex<<hres<<endl ; , g' n' ~8 s6 }2 \  c6 ?
  pSvc->Release();
) K/ g4 s4 Q) I( H  pLoc->Release(); - D) N5 q  {, j( f, [
  CoUninitialize(); * N% y4 z. j2 G0 q/ p5 \; R% A
  return 1 ;
: y5 ~) n$ N6 F; H/ v8 z  // Program has failed.
5 A" l4 A1 ^/ ^. k4 N; m3 x  }
& u" N5 `0 G' P# ^1 {  else 3 f9 f; X, B- F  w# E3 B
  {
' Z3 m) T5 \! a+ r- S) o+ V; |  IWbemClassObject*pInstance=NULL ; $ z4 p7 e- F. G2 D+ \0 b
  ULONG dwCount ; " Z; p! F2 m" I$ Q+ o2 h
  while(pEnumerator->Next( & n" [# a3 D/ e2 f% l1 R
  WBEM_INFINITE, 1 ~8 P6 j; f" L  k+ `9 {7 x
  1, # N) J" i4 i$ H) }9 ~: \8 V
  &pInstance,
" |' N, h) M9 E  &dwCount)==S_OK) 0 a$ h% i' T8 c
  { - k- |" r; o7 [& b
  SAFEARRAY*pvNames=NULL ; 5 D& Q2 D5 w5 o; u% ~# o
  if(pInstance->GetNames(NULL,WBEM_FLAG_ALWAYS|WBEM_MASK_CONDITION_ORIGIN,NULL,&pvNames)==S_OK)
9 J3 E/ m) {( H3 m/ x  {
! `; `  q: T$ H% Y& K  long vbl,vbu ; , ~4 O& x* s- K+ @+ c
  SafeArrayGetLBound(pvNames,1,&vbl); , d& H. y' k, U" _8 e
  SafeArrayGetUBound(pvNames,1,&vbu);
$ ]( B. L' k" g3 y- |, o  for(long idx=vbl;idx<=vbu;idx++) 3 ?2 `3 w7 i& x! d
  {
% h; L& A6 Q( B  j* G# c  long aidx=idx ;
) E3 {. C+ E' _; q6 C6 I% r( _/ z  wchar_t *wsName=0 ; 4 A* [1 w/ [+ z
  VARIANT vValue ;
- @! o1 u& @: \) h  VariantInit(&vValue); 8 C( A( ^( f$ s+ n* E
  
! a" u0 p! {1 l0 b  SafeArrayGetElement(pvNames,&aidx,&wsName); 3 Z3 Y  Q! M/ `
  + Y. ^1 p) M* n3 e6 M
  BSTR bs=SysAllocString(wsName);
' V( A5 c0 ]$ `  hres=pInstance->Get(bs,0,&vValue,NULL,0); % k' g/ I( Y# W% K
  SysFreeString(bs);
1 {% t! g- v6 x+ M: ^  |' z  6 r3 _0 D+ m7 X. j; {
  
1 K- o2 b7 Q. d& y% A% M  if(SUCCEEDED(hres))
+ S0 ?3 P1 s1 U0 T3 u8 J2 X3 |& W  { ! Z* G# A7 Q4 K% _; o# a  V  |3 m# u  S
  char szANSIString[MAX_PATH];
5 |9 [" n/ n8 Q$ v, f" k  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,wsName,-1, ) v  Y! c6 p& y  q5 Z
  szANSIString,sizeof(szANSIString),NULL,NULL); ( }$ r/ |6 \! |- _  P2 ~+ l0 B
  
0 o/ r( ~7 l3 R  cout<<szANSIString<<" : " ;
: v7 M" K4 `. K8 i/ V$ e; g; b  switch(vValue.vt)
" l! N7 `; u3 `" k7 ]- a) }. x, d5 `  {
  P( X* j1 s1 y) Y+ M2 o4 q  case VT_BSTR :
3 m( N' q7 }5 w  wprintf(L"%s",V_BSTR(&vValue));
" s6 ~3 G- Q9 l  v  c  break ; # A  n! Z$ q8 \. t' A; ~6 s
  case VT_I2 : 4 c) ~. @6 t  J, C
  wprintf(L"%d",V_I2(&vValue)); ) y/ \' E6 e2 ]; s* e
  break ; ' M5 i7 n" ~, z% S% C
  case VT_I4 : ! B4 R! X6 L& R; R# L( F
  wprintf(L"%d",V_I4(&vValue));
+ G3 ~& o% T8 J3 v  break ;
4 m. s& N5 a& z# w: ]/ Z  case VT_BOOL :
/ [2 r1 o, S" c( e9 U. _  wprintf(L"%s",V_BOOL(&vValue)?L"TRUE""FALSE");
; O0 J4 o" o+ N5 y, z! _  break ; ; O1 W) r; u' }/ P1 z  Y1 F
  default: ' u/ }5 }1 ^8 Z: U3 Q
  /*WCHAR tmp[100]; ( m: m1 R6 u. `# S( |5 k
  wcscpy(tmp, V_BSTR(&vValue));
+ _: M! K6 y2 N7 w- H  char tmp1[MAX_PATH]; / e" V) ]: F+ Q9 a3 b( ^, e! |
  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,tmp,-1, ' b- l  w& n, `( J1 e: d/ J! ^
  tmp1,sizeof(tmp1),NULL,NULL); ) R7 ~( {+ j7 W7 c! K
  
/ w  v; ?1 E! X1 P. V  N+ g% X  cout<<tmp1;*/
5 w4 s+ M& E/ S* A# h  break;
' }9 }5 \( \* ~1 w+ F0 {  } % c+ |& N! s+ w  ]& i7 L
  cout<<endl ;
7 ]" `3 P9 k/ z" n0 K  }
& A9 K; ^3 [4 |/ j4 R, Q  
$ H# u- c+ I8 L# Z* y  SysFreeString(wsName);
/ j4 G) `; I( a$ X0 ?) W$ e  } 4 ^# z) H6 G( y) S
  ! B' X/ A5 U# d6 k
  }
* r! I; r& N' Y; s  else 5 G2 }, y" y2 V) j
  { $ c3 o+ P6 t$ j/ t5 x$ X
  cout<<"Query for print queues failed. Error code = 0x" : F' M( z8 R  q6 _( ^/ b
  <<hex<<hres<<endl ;
# C8 {5 a( \: n. R' W  pSvc->Release(); : [( `  R+ m0 {
  pLoc->Release(); 9 c0 d( d) a" h; d1 j- ^& l
  CoUninitialize(); $ Q* V9 Y! x) g8 e
  return 1 ;
( J: }% y. K% j9 f6 R& T  ~; q, w  // Program has failed. # {- W% R) [& n2 K& C
  } 3 J- R- m) A( z, O( v! a
  if(pvNames)SafeArrayDestroy(pvNames);
6 i4 [6 b, ]$ W4 R& `! O  }
+ R) {9 L: `; i; J4 @; A/ ?  if(pInstance)pInstance->Release();
- `: {* Q% G, W2 L5 z6 ?  
  L, S' W8 j7 N# k" A  } 2 H. T; a0 r9 B  E( K
  // Cleanup
5 R$ j. P( v( T: T, D  // ======== 5 p7 I  I8 ]  `6 j
  pEnumerator->Release(); - t8 v( }0 h: S1 ^: b. w$ D5 n0 `
  pSvc->Release(); . O4 B: L1 c/ F2 ]
  pLoc->Release(); * b7 G* [: e1 C; |, k, p5 O
  CoUninitialize(); - P. [* M4 |/ B( f
  + ~4 S  [! n+ `* A
  return 0;
  n/ D8 ^- s1 y  b  // Program successfully completed.
8 O0 i/ w. c% R& `# |# i1 n  } 6 ~) ?# C3 X7 W& Z* ]
  //-----------------------------------8 T- ~2 a7 H" q9 `
    W" m# n" R, i4 ]* ]8 i: e, u
  对于怎么用BCB编, 感觉还容易一点,因为我在类型转换的时候碰到了一些问题,而在BCB中的Variant类做了比较好的封装, 具体代码可以 http://www.cppfans.com上找到.
+ A$ D" u# Z* W- H- t  
. U0 R( ]( R: r/ L6 W0 Q! j  void GetWmiInfo(TStrings *lpList, WideString wsClass)
5 c: [  V; ?1 G! b2 b9 ~  {
% k. Y( X! j& u/ e  R  IWbemLocator *pWbemLocator = NULL;
$ j$ N9 }. Q5 Q8 }7 M: p  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)
" o5 h  O1 Q" o. n2 ]- G  K7 C6 M" j  {
- X2 w/ g& C6 `1 |/ Q. C$ @  IWbemServices *pWbemServices = NULL;
$ {% b4 O5 V; Z, F- M8 M# X  WideString wsNamespace = (L"root\cimv2");
+ A4 e& o( s# u! g& p* S  if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK) 3 W1 k4 _/ o2 O  c
  {
/ E, ~5 X6 V) i0 U  IEnumWbemClassObject *pEnumClassObject = NULL;
6 i! @5 A3 \2 }) Y% X% t  WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass; * P- }7 Y$ O0 U0 i5 O3 D
  if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK) - [+ v. V# _0 h6 u
  { % y5 _; z1 @; S4 v9 z
  IWbemClassObject *pClassObject = NULL;
7 j  a' a, j; T6 j  ULONG uCount = 1, uReturned;
; ]- j9 w" w9 A. j8 U4 u/ i  if(pEnumClassObject->Reset() == S_OK)
% i2 a1 ~1 {& m# P0 Q6 _5 `, Z  {
0 M# @4 v  K) S6 U1 y  int iEnumIdx = 0;
+ M$ K2 e% |  ?( P2 {, C! Y0 m  while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
  e% M$ z. s% {6 k# }% s  {
2 f- \3 p* F: S, X  lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------"); : p, \, |1 L# c  d3 [
  # A5 `$ _8 T! @$ g8 s/ z
  SAFEARRAY *pvNames = NULL;
- p0 z4 i6 c5 n4 P  if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)
# J' h, _5 }1 r3 c2 J, _  {
$ M  w/ `& T/ q; B; q  L9 u# ~! f  long vbl, vbu;
* ?5 z" i9 g( o$ ^4 k  SafeArrayGetLBound(pvNames, 1, &vbl);
$ `% ]7 @- I' L1 l3 f) q/ C! i* i  SafeArrayGetUBound(pvNames, 1, &vbu);
) U( M3 ~, ^1 @3 n  for(long idx=vbl; idx<=vbu; idx++) ) Q! K5 z: u) X+ R
  {
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-8-14 00:59 , Processed in 0.018037 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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