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

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

[复制链接]
发表于 2006-4-16 18:40:38 | 显示全部楼层 |阅读模式
    一直以来都没有用过WMI, 都是用的PDH来获取系统信息.感觉两者很些相似,都是类似于性能数据库,基本的一些什么硬件软件信息都可以比较全面的获得.只是用VC来调用相对比较繁杂,用VB和C#就方便多了.这些天到MSDN上找了些资料,总算大致搞清了一些编程思路.对于那些很想知道怎么获取诸如CPUID,硬盘ID,BIOS信息以及主板信息的人来说应该有些帮助吧.试着用MSDN的例子乱写了一通,以下是通过WMI获取BIOS的例子,不对之处还请指正 ^_^: - J$ U' h+ [+ i4 ]  g; j
  --------------------------------------------------------------------------------
/ }+ o2 Y% c% `7 n* e  I  #define _WIN32_DCOM
  P9 [: i/ y& F+ k  #include <iostream> / p2 q0 ~0 W7 h
  using namespace std ; . Y! J7 n8 r1 ^. r6 H7 y
  #include <windows.h> 4 [5 y; K9 O" R8 w
  #include <comdef.h> 1 X0 g, v! }' K+ D; i
  #include <wbemcli.h> 9 _  \2 ^9 H5 m/ h0 @5 _4 `
  ; J7 p8 B; c$ z/ n" b1 j5 _6 r3 X
  #pragma comment(lib, "Wbemuuid")
  \" {5 ]& @* T( f  
7 V$ `' J8 U4 a: v3 ]( w" N  int main(int argc,char**argv) 4 W! }- Y; ]' S* x" a# R
  {
" B( P. o0 A# `+ }0 r( x! u! z/ [  HRESULT hres ;
$ a& ^+ ~% e5 [' n  
9 ]% j3 r) q6 L$ T" g0 h$ `* [" b  // Initialize COM. , P5 r8 S. a" M7 w
  hres=CoInitializeEx(0,COINIT_MULTITHREADED); $ U- M1 Q/ `6 l5 w  l7 W7 \, f
  if(FAILED(hres)) 7 ^% V" P+ d3 F+ S0 c; G
  { 0 D! f+ ^) {& H" K% ?
  cout<<"Failed to initialize COM library. Error code = 0x" 0 }1 g% Y, _7 U3 m2 z9 _2 h
  <<hex<<hres<<endl ;
- B5 t  g% w9 q' |  return 1 ;
2 v* t2 v- J9 g; P" z& W$ e  // Program has failed. # g  e$ v4 X: D; b- n# ?
  }
: q- Z6 w' S% H, x, h  
' f. e# \* o$ w0 W( D, {) r$ H  // Initialize 5 R4 @, R! k5 o
  hres=CoInitializeSecurity( 2 Z5 o% W. W0 N0 y. @1 y
  NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_DEFAULT, / r6 N+ a9 O. K5 v
  RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE,NULL); $ `6 T; z1 G6 q( r
  ) P# n% V$ k# z6 m# m6 Q
  6 ?0 ~- R. f$ v
  if(FAILED(hres))
1 B/ t) N9 Z% \6 N  {
( e% h1 \% A: r  cout<<"Failed to initialize security. Error code = 0x" 5 r; z. V$ H* a& G
  <<hex<<hres<<endl ; # u! B  n) I3 g" j
  CoUninitialize();
7 |+ F4 v6 l7 O  D/ K4 H  return 1 ; ' s# H8 r6 R3 }" \
  // Program has failed.
, k; e% ?9 v! G) R  }
; e. k- N9 P# W2 u  
" }/ w- O; O; n1 g1 {  // Obtain the initial locator to Windows Management on a particular host computer. 0 c) G) D9 y: r# ?6 P" C# k
  IWbemLocator*pLoc=0 ;
/ I: _/ U% c, l  
& f# m' u9 x. R* H  hres=CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER, 0 l% {7 S% a( j* M0 Y+ p
  IID_IWbemLocator,(LPVOID*)&pLoc);
' r1 S) P; [1 u* v. k  
3 U6 @* Z# z( M& e0 y1 D0 ^3 H7 Q  if(FAILED(hres))
. \, V9 C5 x  \: u+ {' Q" t' ]$ l  g  { 0 O7 t, C4 }/ @
  cout<<"Failed to create IWbemLocator object. Err code = 0x" $ a7 S+ M( S2 `! M* }0 s! [
  <<hex<<hres<<endl ; - T# y7 t4 |; h- D9 |7 J$ I
  CoUninitialize();
; E9 \" g# X8 V& A$ z6 u  return 1 ; + p+ n$ \* E# o& Y! R
  // Program has failed.
- u5 m! ]' u8 O* M; J  } * z1 a* h! s- o/ O! q- ?
  4 P" ^/ P$ b3 N" P% X
  IWbemServices*pSvc=0 ;
' q- Q3 v$ r$ P/ y/ a% S% ]7 V  
' c( A6 D+ s( O. i( J. c  // Connect to the rootcimv2 namespace with the current user and obtain pointer pSvc
' P* G( C9 g( l: o  // to make IWbemServices calls. 3 s9 S7 q8 b2 q" f8 e8 r
  
$ j: l& {$ V8 d  hres=pLoc->ConnectServer(_bstr_t(L"ROOT\CIMV2"),
2 B, F9 o- T7 j8 t$ s( |5 j  NULL,NULL,0,NULL,0,0,&pSvc); 2 P* g7 q( W0 H" \4 B% w
  ; I" N& i" @  f8 T/ }! q6 ~
  if(FAILED(hres))
# K- g6 I5 W4 x, }, O- Q# a! ]  { + s9 |4 q. v6 J
  cout<<"Could not connect. Error code = 0x"
! H! m' b2 g* T8 e  <<hex<<hres<<endl ;
# W* S6 N+ n( V& B9 m  pLoc->Release(); . f6 J& y+ V7 q# n, @- }" C5 \! y
  CoUninitialize(); ; g+ r4 \. w7 ]2 t- |
  return 1 ;
# {8 j* h$ C9 i4 {% ?0 |2 f. @% Y) y  // Program has failed.
9 T2 V3 l4 B! W6 A% Q; ]' ~. P$ a( X  } % q8 T6 x* G- N1 c6 l' e0 t
  
1 g  |1 a4 g+ z% [' U  cout<<"Connected to WMI"<<endl ;
/ I! F% A% ^% [" G: u' J  # t# H0 g5 h" |9 H
  // Set the IWbemServices proxy so that impersonation of the user (client) occurs.
, E7 T6 m6 l+ Y* M2 i9 q) R  hres=CoSetProxyBlanket(pSvc,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,NULL,
$ I9 O! P; f- c# P+ y' c4 q  RPC_C_AUTHN_LEVEL_CALL,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE);
7 A9 Z& x* W: l- i  ' }: W+ G( J" [5 {, j3 y
  if(FAILED(hres))
" d' U, i8 r( E; S  { / W7 z2 C% E7 F. E
  cout<<"Could not set proxy blanket. Error code = 0x" 0 Z7 G; M5 o7 m4 p! T
  <<hex<<hres<<endl ;
5 V+ h7 d: f4 J2 o  pSvc->Release();
" r* x" Q7 s4 j  pLoc->Release();
, v$ X; j  n6 i# a# t  CoUninitialize();
( u' _$ ?+ A9 k$ @  return 1 ;
6 @& h! T; u5 i) ~8 b' Y1 c  // Program has failed. , s8 o$ M% X" J/ T- n( B) ^
  }
+ N8 B! e4 |) h8 _& X. K  
% h1 E' c/ ~: q. I  : J; K3 }) w! T
  // Use the IWbemServices pointer to make requests of WMI. % X2 {8 Y( b3 R* i
  // Make requests here:
9 T# y& [& c$ M3 \. _& w, \7 X& D  
+ {" _9 f; o. R( P& @( R. q  // For example, query for print queues that have more than 10 jobs
) M6 C. k/ l: v) y6 d+ N6 N  IEnumWbemClassObject*pEnumerator=NULL ;
% m1 i- B+ Q" e& G, C  n* v. u' O  hres=pSvc->ExecQuery(
2 l) F( c1 W- M4 ~! d  bstr_t("WQL"), 4 c) o+ O& f/ c9 G
  bstr_t("SELECT * from Win32_BIOS"), # q3 N2 H. B9 A4 X1 k
  WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,
  w5 `! j' F) s  d  NULL, & `  w1 b# T' z" U4 n- ~
  &pEnumerator); : r9 C" w, g$ B# E
  
  Y" U# r7 ?: h- [6 [  if(FAILED(hres))
0 T0 d9 s+ w2 u5 X  {
$ }* \* R9 k2 ^5 V6 U* D  [% ]5 ]2 w  cout<<"Query for print queues failed. Error code = 0x" & G+ f6 b1 z8 j3 N$ ~# k
  <<hex<<hres<<endl ;
) N% l) ~, Y. {6 t7 s0 H- U  pSvc->Release();
( t* E. D* k, `  pLoc->Release();
6 T4 @. P6 V7 r( F- j8 _# m  CoUninitialize(); 3 R( U( Z6 S3 q3 \: z& Z3 E# c
  return 1 ;
8 `" K3 {$ o( w  P% d  // Program has failed.
/ j" R8 _! c6 t, Q# J# j  } : M  d9 O. q3 H# x5 P
  else
  x# ^! ~9 ?6 V+ v0 U  {
' }7 B0 q, A2 v  d+ ^  IWbemClassObject*pInstance=NULL ; 9 E7 E. w6 ~2 U3 D/ d" L' d
  ULONG dwCount ;
6 Y. Y4 p8 j8 {' M, ]  while(pEnumerator->Next(
' ~* T+ s8 V5 q  WBEM_INFINITE, $ |5 G( h) o& i+ s7 H
  1, + S! d% [0 l- b
  &pInstance,
7 q* q6 B2 C6 f# q& b8 W2 j2 D  &dwCount)==S_OK)
/ Y9 B4 J5 @- A8 b3 X8 a  { 2 K; [3 l  g. o! ~/ @  I
  SAFEARRAY*pvNames=NULL ; ; r+ S: P( I2 q. e( g+ t, \0 ?
  if(pInstance->GetNames(NULL,WBEM_FLAG_ALWAYS|WBEM_MASK_CONDITION_ORIGIN,NULL,&pvNames)==S_OK)
1 N7 R8 }$ x5 Q9 h7 h, ~  { $ N: d$ y. {  i0 s
  long vbl,vbu ; $ Y$ C  T7 T9 ^/ ~# k
  SafeArrayGetLBound(pvNames,1,&vbl);
/ k- v  t# ~. J$ p& C  SafeArrayGetUBound(pvNames,1,&vbu);
6 X% d* M; V) |5 x6 e  g  for(long idx=vbl;idx<=vbu;idx++) 4 D. U; `0 X0 n2 \2 j" a+ C* h. j
  { ! R( ~: w7 t7 C* ?+ \8 j$ f
  long aidx=idx ;
& J$ z% Q! N- h4 {0 X  wchar_t *wsName=0 ;
+ X6 _) R( k6 m6 V1 G& i  VARIANT vValue ;
# }7 K. b$ L% X: Q  VariantInit(&vValue); / e3 }* q: O& d" N+ X
  
# \  H+ B$ H3 ~, r" }) ~  SafeArrayGetElement(pvNames,&aidx,&wsName); 5 y% V! M  S1 K# S& L( O4 [6 {
  
* w! D0 |0 I. a3 ?/ a( k/ K* F  BSTR bs=SysAllocString(wsName);
/ A0 P0 K, ^4 u) y, q" V  hres=pInstance->Get(bs,0,&vValue,NULL,0);
4 Y) e# h. Q- a. r: j  SysFreeString(bs); ! ~& I0 Z: C' [5 a, J9 s
  
9 n7 D  R. t5 R0 V* F1 l$ j  
. Z' a& [. ?$ g& `  if(SUCCEEDED(hres))
" `; [, _9 x" X% E" j, y( |( p  { 8 W$ [( K8 O( a# n
  char szANSIString[MAX_PATH]; & T2 h( Z8 \7 T- \' g
  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,wsName,-1, % Q. X! J; Z* t3 t  |
  szANSIString,sizeof(szANSIString),NULL,NULL); ( U# @! r2 Y. I
  ( J4 i+ U) q; b
  cout<<szANSIString<<" : " ;
0 u# n" r/ p( \; l  switch(vValue.vt) 4 Y! z( n! j+ ~, R+ C* @
  {
9 u( Y+ b5 v# S  case VT_BSTR :
2 J$ p( r( f, H; W9 `  K1 c  wprintf(L"%s",V_BSTR(&vValue));
( r- i( f% ~/ `% e  break ; ) l' D/ F0 J# |# l: L+ b/ F
  case VT_I2 : ) a3 u7 I" ^$ B+ `5 U( g
  wprintf(L"%d",V_I2(&vValue)); ! m3 O/ n2 `( v' m! ]/ Q; U
  break ; " |8 r0 T( d. k
  case VT_I4 : 5 `7 ]2 d: X0 I9 \" K8 H
  wprintf(L"%d",V_I4(&vValue));
$ j) Z; R, v, {+ N( W# s+ _  break ; * d9 f) E- K' ^) o0 k
  case VT_BOOL : 3 K2 ?% G$ j  V* {( ^
  wprintf(L"%s",V_BOOL(&vValue)?L"TRUE""FALSE");
  q1 U' \9 {& `6 Z  break ; # R) w5 t- Y3 O5 f7 h8 V
  default:
: H. a) t2 Q5 ?4 ^1 i7 C. P  /*WCHAR tmp[100]; " O. @' k3 X7 v
  wcscpy(tmp, V_BSTR(&vValue));
) O( X3 e! h: u1 m  char tmp1[MAX_PATH];
9 j0 l% j) ^! b2 t% O7 ^0 W  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,tmp,-1, ' G" `) {+ h! M! Q; f
  tmp1,sizeof(tmp1),NULL,NULL); 3 Q0 z" k# w+ _& K; X3 i6 f
  
6 p2 i( p/ {1 u( f1 j) ^  cout<<tmp1;*/
5 R/ W  C8 O) V% q, p0 I0 A  break;
( @6 p1 A- v1 F, r  } + D" u* @) `- e! b5 C8 Y- X
  cout<<endl ; ; x% Y, ]+ B) b% H5 L" [
  }
! W* Z, K$ `" b- b% A  ( P0 ?" D  X) P6 t& l* Y6 W4 j
  SysFreeString(wsName);
+ O% V3 j1 J- Z- a& m/ `& |  } + z8 V8 x) o2 \4 X3 o& D# T
  - T6 ^! v% h0 \
  }
9 u2 c. m4 B: F) A, y& V" |  else 4 w- S# ~0 f2 O! P$ a' T
  { ! v- Z# Q+ I$ K% s- _6 |- J+ A
  cout<<"Query for print queues failed. Error code = 0x"
/ f( F. b' l4 w  <<hex<<hres<<endl ; 8 L6 B9 E3 Z( N) g5 z
  pSvc->Release();
/ R, A; }  G6 [- f2 M2 y  pLoc->Release();
, ]* _2 o8 e+ f5 t0 c  L! l  CoUninitialize();
2 ?, z& o5 |5 q1 d  return 1 ;
% g* j1 [, H- U- R0 q' Q: w( B0 T  // Program has failed. 0 B9 H3 n: _4 U" d. }9 ]0 W
  }
6 P! K8 R% p; ]+ s7 D" ]  if(pvNames)SafeArrayDestroy(pvNames);
1 R; m6 S/ v. L5 i( }2 c, A  }
8 g+ H. w7 D8 d  F+ R! M  if(pInstance)pInstance->Release();
) g1 r' k7 C( r  
5 P3 ]" ]  M' f0 a9 d* z  }
) Z5 X. O/ |: F4 J* Y  // Cleanup
7 Z: o# g/ @( f/ C1 t' S  // ========
" k1 k# S5 \. }  pEnumerator->Release(); ; h% ?" H* V/ O, U( t+ t
  pSvc->Release(); 8 X  x9 w/ ~6 }' E2 k1 ^( k
  pLoc->Release();
5 [/ o% B3 X0 J3 m  ]8 t" r  CoUninitialize(); 9 e, H* ^' d  _; `# P; X
  : w, @! h8 s7 Q6 m- B. d
  return 0; 5 D8 Y3 w# u: k! ?0 t: M, m
  // Program successfully completed.
; j: O4 R  y  Y" e3 U8 Q  }
5 L9 ~. Y( i- ]0 M0 c* b! @  //-----------------------------------$ ?0 I% X' t: E) ?% b6 @1 u2 Z
  / \' v4 W: B9 @
  对于怎么用BCB编, 感觉还容易一点,因为我在类型转换的时候碰到了一些问题,而在BCB中的Variant类做了比较好的封装, 具体代码可以 http://www.cppfans.com上找到. , X% ?% A. D# Z
  
) L$ \  G  z5 j4 V, f  void GetWmiInfo(TStrings *lpList, WideString wsClass)
& g0 ^- M' e8 p8 n  `  { 2 F7 O, ~3 U+ o
  IWbemLocator *pWbemLocator = NULL;
' |9 M& M7 q+ P$ B  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)
; ]. c0 t2 F" ^: T  {
/ x& p  M! `2 C0 n' O2 ]  IWbemServices *pWbemServices = NULL; 0 U, J, @: p7 O! ]6 b; S& C) A
  WideString wsNamespace = (L"root\cimv2");
3 e& I2 K8 X) t0 [/ R9 X  if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)
/ n- V$ f0 i, @" X9 X  {   r1 I% j# y+ K$ p1 o+ r
  IEnumWbemClassObject *pEnumClassObject = NULL;
: d1 H' \0 X1 ?  WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass; 8 \3 o; Y5 Q$ _0 ~% C
  if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)
: D' z$ l4 C3 ^; v  {
% c$ n% K& B6 u" G  IWbemClassObject *pClassObject = NULL;
: f9 F, p) g6 g( t  ULONG uCount = 1, uReturned;
$ `& K! T& H% p& @$ X  if(pEnumClassObject->Reset() == S_OK)
$ z5 Z- p7 s+ b" c" J( Y0 s  { 5 r2 |  _! W: N- h: w
  int iEnumIdx = 0; 5 J5 t! V1 K, l6 }8 Z; f
  while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK) * |4 K9 [! v8 _$ ^. t" n0 |- @
  { ! x% n0 |: a$ U% Z% n
  lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");
9 K8 `- s, _: V4 o& d( l  5 J! d3 N$ b2 Y* w+ a" I
  SAFEARRAY *pvNames = NULL;
% z4 Z# E1 t* Z* R  if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)
( L+ B/ d# I7 o8 T6 p# S  {
  @. k. I3 t' x; p$ w  long vbl, vbu; / V" Q3 ~( U1 B4 |8 m
  SafeArrayGetLBound(pvNames, 1, &vbl);   ~% Y* H. r0 L/ n6 |
  SafeArrayGetUBound(pvNames, 1, &vbu); 7 A) `) J. X% |- d% ^6 S& t! p
  for(long idx=vbl; idx<=vbu; idx++)
  ~1 a! S, U3 C' |2 }  {
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-18 06:48 , Processed in 0.019307 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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