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

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

[复制链接]
发表于 2006-4-16 18:40:38 | 显示全部楼层 |阅读模式
    一直以来都没有用过WMI, 都是用的PDH来获取系统信息.感觉两者很些相似,都是类似于性能数据库,基本的一些什么硬件软件信息都可以比较全面的获得.只是用VC来调用相对比较繁杂,用VB和C#就方便多了.这些天到MSDN上找了些资料,总算大致搞清了一些编程思路.对于那些很想知道怎么获取诸如CPUID,硬盘ID,BIOS信息以及主板信息的人来说应该有些帮助吧.试着用MSDN的例子乱写了一通,以下是通过WMI获取BIOS的例子,不对之处还请指正 ^_^:
8 h8 Z: ~7 O) h6 f" R5 B( U  --------------------------------------------------------------------------------
! A! m4 _- Z7 l1 y  #define _WIN32_DCOM " R9 n+ O/ i6 ?' d
  #include <iostream>
/ r$ O9 A: z2 T: f+ \4 Z% h. Q3 i  using namespace std ;
$ @4 T3 I5 l! K. o  #include <windows.h> , V" [, z# _4 b# X0 ?1 x
  #include <comdef.h>
3 G: E4 ?& \/ m0 Q9 _: N  #include <wbemcli.h> 2 F/ F$ O$ Y" L9 I+ K2 }0 N/ G! o
  
+ V; j6 `7 t, m% X' m  #pragma comment(lib, "Wbemuuid") 0 }0 {0 D$ p0 @8 v* l0 c9 R+ V
    e% h8 P/ N1 W" m) v
  int main(int argc,char**argv)
: p- U/ F& y& W% r! ?% b  {
& T% I, d+ y. W4 v' G: M  u9 h  HRESULT hres ;
  \5 y) h5 G2 T9 g  e  6 f4 I% Q  `/ n
  // Initialize COM. 8 R: W/ A; V# k" D( |1 K
  hres=CoInitializeEx(0,COINIT_MULTITHREADED); / Z1 |4 S/ p1 u  c4 F; P
  if(FAILED(hres))
0 {: q+ d0 g+ \9 E9 V4 a. L  { ) i. {0 i4 N1 X: v8 N) W
  cout<<"Failed to initialize COM library. Error code = 0x" + d$ k* L' G/ U4 K2 E7 G) B2 @
  <<hex<<hres<<endl ;
. Y5 q& }2 w# i  return 1 ; 1 }* z1 K& a/ G' |$ A  G
  // Program has failed.
8 h" m! t5 F$ E; i8 c  } $ }) P1 z# Q7 z6 {
  5 ~1 Y" V, f) C. C% r9 J8 `* h5 y2 z& I6 O
  // Initialize ( v/ V* w! w% |, z+ l
  hres=CoInitializeSecurity( 5 _9 M- e/ `8 k$ E7 t
  NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_DEFAULT, & L& G* K& q7 d7 H5 z2 n
  RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE,NULL);
+ X/ {% K% e# D  E  
2 m. G. z, _9 n% i* x  + H' S$ F* f  I& Q& v, u
  if(FAILED(hres)) * ?& [! [" T- ], n! u5 r" H
  {
; g4 W- X' F/ s, q! t: ~$ l- x  cout<<"Failed to initialize security. Error code = 0x"
/ h8 p3 \+ S$ a, h4 W9 f  <<hex<<hres<<endl ; $ z1 e# L9 T8 z; \( i
  CoUninitialize(); 7 r! J8 O, `) g2 ?/ w4 b3 g
  return 1 ;
! X9 t: `; R- C+ f% `3 ]  // Program has failed.
: {$ g/ N, K2 ^5 n  }
' t, B4 P- V1 Y) s, U* V" |  
6 f( f' }* D9 K' ^/ j. m  // Obtain the initial locator to Windows Management on a particular host computer. ! Q% b1 q9 C! s1 T0 `/ D' c# O
  IWbemLocator*pLoc=0 ;
0 D# J  l/ C% M% ?4 z4 G2 T  5 d+ n+ H; f( h
  hres=CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER,
) B; ~: z, h& ^6 Q/ @3 e  IID_IWbemLocator,(LPVOID*)&pLoc); ' V' ~0 _9 {- V
  2 A0 R5 u6 R: G# Z' H" t% Y
  if(FAILED(hres))
2 q9 \7 u  Z% J( ~; N7 n  {
/ g. V, |  H% L/ N/ j$ F3 U  cout<<"Failed to create IWbemLocator object. Err code = 0x"
$ U9 c' y9 V. F" W* ?/ ~" Z  <<hex<<hres<<endl ;
; a! ?9 W1 `' b+ k+ s  CoUninitialize(); 8 S# v7 H. H0 U, Q# K' w( y0 b
  return 1 ;
0 g( h8 j2 V% e+ i  // Program has failed. 5 T0 ~1 \# V) N- H, A
  } 0 p3 f/ j+ k. d, n
  
* D% ]- w' r1 l+ K) L" W' a3 o  IWbemServices*pSvc=0 ;
1 Q: S( a# x- e& [  ! b5 f" k/ a; O
  // Connect to the rootcimv2 namespace with the current user and obtain pointer pSvc
# {' F- A; Z$ G: s  I1 ^" j7 `. S  // to make IWbemServices calls. % m% G! V4 S# n- L8 t- S1 H
  
+ d% v. s3 T/ X+ a5 ]  hres=pLoc->ConnectServer(_bstr_t(L"ROOT\CIMV2"), ; ?0 K' k4 Q' R6 I: o6 i4 y5 v
  NULL,NULL,0,NULL,0,0,&pSvc); 7 j- R* E9 ?( b, `
  
6 r1 G6 \7 [( v; x, d% Z* o  if(FAILED(hres))
, e9 I" r$ [9 |1 Y  { ) v% @  n( l8 j+ c6 G" c& I% }  Z
  cout<<"Could not connect. Error code = 0x" : V, g! U) z0 w$ d+ N; b
  <<hex<<hres<<endl ; 2 M: l, E8 Z( _  p0 g
  pLoc->Release();
: V& ]" g( o: z  CoUninitialize(); ( J# B) J& L6 v; {: L( c
  return 1 ;
( ^/ D4 S/ O1 W  // Program has failed.
+ N& _" C, B8 C% d7 x+ m1 K6 }) e4 l  }
" W' P6 u7 J/ ~5 P, W% b, h5 K* j% ?  8 {+ l# \' V# \2 F
  cout<<"Connected to WMI"<<endl ; 6 n4 l; Q: X+ C4 z/ |& H) M
  6 l  ]) j" d" m0 f$ r' l) w" q0 m
  // Set the IWbemServices proxy so that impersonation of the user (client) occurs.
/ s- ^+ G7 H: _% b  ]4 w  hres=CoSetProxyBlanket(pSvc,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,NULL, ' j0 \1 u& ?" V( f3 y4 R/ b
  RPC_C_AUTHN_LEVEL_CALL,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE); ! u. n! t1 P" t; P  R- i
  / w% {# ~/ f0 j0 F# x" c
  if(FAILED(hres)) % w. @0 I$ }( B+ N2 |* ?% c& g
  { * o- r" c. u- `" Z) s: J
  cout<<"Could not set proxy blanket. Error code = 0x" 9 z7 Y1 _0 p: b6 f& r0 \" R
  <<hex<<hres<<endl ;
& A+ d8 O4 T, X, x, ]6 v8 Y  pSvc->Release();
& y0 O  r2 _7 d: ~! I  pLoc->Release();
9 T6 f/ \/ [3 z9 U) W; r  CoUninitialize();
" f$ p: w9 k9 q3 L  return 1 ;
9 \) e1 O# U- [0 _  // Program has failed. % Z* O9 i0 c9 R* p0 X6 w* {0 k; z! g% e
  }
! z( Q+ V. s2 l! F! n  
& k. p& l* b  C7 W' `  3 I9 H) b/ z+ o) y( C7 R$ i
  // Use the IWbemServices pointer to make requests of WMI.
# L  n# k( a1 }; S  // Make requests here: $ i6 \" y- l4 t
  
3 o: c4 m( Q1 R4 @  {8 l! ^  // For example, query for print queues that have more than 10 jobs 7 ?1 Y, a# H  I6 }# N; \& |( P
  IEnumWbemClassObject*pEnumerator=NULL ;
* p& Q) g% ~6 x  y  hres=pSvc->ExecQuery(
2 t* e* P3 s! X2 W% H# J* l( I3 Z  bstr_t("WQL"),
& t- z& d/ ^* f4 |+ x- _9 }  bstr_t("SELECT * from Win32_BIOS"), # A) f- b9 W& {- j  R
  WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,
5 b" n1 S8 g9 G  NULL,
7 g% m0 J7 a+ J! r( Q- U  &pEnumerator);
# ?5 L. y7 T5 r  R. N% P$ x( X  ' j  R6 h7 b' w0 Y# Q# E4 U
  if(FAILED(hres)) 4 ~# J! N& G+ ]1 O9 J7 ^7 C" j
  { / G% \1 {( K5 q
  cout<<"Query for print queues failed. Error code = 0x"
2 C) C' U4 D# {' y* R  H! D  <<hex<<hres<<endl ;
+ f* }( X: l) x  pSvc->Release();
7 ^" O* D# e9 ~# ~; s8 j/ G  pLoc->Release();
8 `  B( J0 o1 a, t! r% \  ~; l  CoUninitialize(); ) P( X. o' x" F# G* p6 O+ n" d
  return 1 ; / K4 D: j' m  s) K( }
  // Program has failed. # @( o& I' Z6 ]3 J" p1 O$ _
  } # ^" |: Z' R* i! e
  else 8 A$ }: |/ M' N
  {
1 \; O# v+ w: _  IWbemClassObject*pInstance=NULL ;
; `3 J! `6 o- N" `# v  ULONG dwCount ; ( g) i  X6 E/ z8 V8 q
  while(pEnumerator->Next( 6 l0 t2 x, Z5 y: @
  WBEM_INFINITE,
- l& p9 H$ b; Q" i  p$ [  1, ; O. R% |6 Y. K. q! m5 b. e5 V9 ]
  &pInstance,
* l/ L; ?; v8 u7 W- M% a  &dwCount)==S_OK) # O1 d1 y; `" M7 P3 P6 p, n
  { 7 q$ |. K' X8 U1 O: H
  SAFEARRAY*pvNames=NULL ; . u, d- q: d4 h+ J3 A
  if(pInstance->GetNames(NULL,WBEM_FLAG_ALWAYS|WBEM_MASK_CONDITION_ORIGIN,NULL,&pvNames)==S_OK) 4 Z) o* N, l( R8 A5 i
  {
" g" M$ y8 x/ e+ Z4 N  long vbl,vbu ;
( d& Z: m  [' l; a" P  SafeArrayGetLBound(pvNames,1,&vbl);
! X2 ^# E! U* O( ?  SafeArrayGetUBound(pvNames,1,&vbu); / L* A/ Q# P" i, w0 ]
  for(long idx=vbl;idx<=vbu;idx++)
" N0 M/ ^/ |2 ^$ m% @  { ' t. v" h4 I# ?4 O9 o/ @; g
  long aidx=idx ;
9 z  U3 Q: d6 P  wchar_t *wsName=0 ; ( E; R- {7 ~7 [3 o+ E6 D
  VARIANT vValue ;
6 f8 m( d. @0 j+ A8 N8 }  VariantInit(&vValue); * Q3 \/ P% _3 h. V  n. o
  
3 Z! b" E, [. w; W# j! E' T  SafeArrayGetElement(pvNames,&aidx,&wsName);
! A1 o- |  _' E# G: a4 \  + S# t+ R/ t; a9 e/ P( t% v$ j
  BSTR bs=SysAllocString(wsName);
. d) ]' `( ~: W' T7 w  hres=pInstance->Get(bs,0,&vValue,NULL,0);
  Z& A* C) p3 j' H  SysFreeString(bs);
, X" u3 a/ v  @$ s) e  
8 |- {* P; }  L4 h2 M9 f/ ?2 Y  
" n. M4 o/ {/ Q: `/ z5 W" s1 F% f  if(SUCCEEDED(hres)) % B, K1 g! `* P6 N. q
  {
9 k* u* b* M) X  char szANSIString[MAX_PATH];
( E: j- y( P1 |  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,wsName,-1,
6 H4 Y3 y3 {; Z: O" ~1 |  G! j( Z  szANSIString,sizeof(szANSIString),NULL,NULL);
2 B1 S; j; b: J& f* U5 U  8 ~( G; m/ m- E7 _
  cout<<szANSIString<<" : " ; ; m+ w5 Y7 c( e
  switch(vValue.vt)
+ J( x& v0 ]) F) F6 y% m, U# G- z  {
; x+ j! L9 f- z  case VT_BSTR : + J( P0 ]& B- n" j! i5 K( F2 g6 r
  wprintf(L"%s",V_BSTR(&vValue)); # Y* F4 o" n# A+ b& O
  break ;
  c3 `1 d( R9 ^/ f! Z( |, ^4 T  case VT_I2 :
$ B) V' y, U" S. z  wprintf(L"%d",V_I2(&vValue)); 3 n2 u& i) t. j+ X4 S* N3 O
  break ;
5 n7 W8 O( D9 p: @+ e+ p( y* t  case VT_I4 :
! j1 u7 s0 _- b/ w1 B& Y5 E  wprintf(L"%d",V_I4(&vValue)); 8 s; ?6 t5 v  w* `. F
  break ;
; e8 B" T3 u- T0 p2 t! X9 L0 ~8 W  case VT_BOOL :
. h8 E% l, I$ ]( G" Y4 a  T- }0 O  wprintf(L"%s",V_BOOL(&vValue)?L"TRUE""FALSE"); 8 l3 X! d0 |+ W' M- [
  break ; 7 }: V1 Q6 a/ ]$ n. j
  default:
1 ]* l4 }6 W" J3 v4 R# H  /*WCHAR tmp[100];
2 |0 B! i  s, H! v9 J& x% G6 r* E  wcscpy(tmp, V_BSTR(&vValue));
4 F. o8 v* y( K4 V/ |  char tmp1[MAX_PATH];
/ k! o( J: ^( Q0 Y- F2 L, {  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,tmp,-1,
9 \) S) p- j! T  tmp1,sizeof(tmp1),NULL,NULL); / d' }' e3 D  C6 W! T! {+ {) w
  % |/ p: b1 V, x2 ?9 `7 A
  cout<<tmp1;*/
* _% Y9 F  L% ^* Y  break; ) L% V# Z2 k& y& e
  }
% V5 b( I* L" O8 X  cout<<endl ; ) W/ j' v" K7 Q" s; J. v
  }
8 p* X) K4 s& c1 E. g+ w7 W  $ N/ \: ]) t8 V2 b6 [
  SysFreeString(wsName);
/ W* \0 ?; P2 u- [) w2 u  } 4 t3 G5 c; k3 R. ^6 O/ Z# ]. I5 |
    q' C% I+ ~) w8 L
  }
" A# n9 e" e0 I1 N7 U+ G  else 0 w3 y! f+ ?& e1 @2 w
  { / X& c  g% B: |- ]
  cout<<"Query for print queues failed. Error code = 0x" # u7 \2 K/ V/ l8 w
  <<hex<<hres<<endl ; $ Q4 m4 H) J0 V! C! H" x" p
  pSvc->Release();
; k9 U2 a4 J1 h( N# s; K  pLoc->Release(); % s& ~! g+ z( m. x6 l2 }, A" b
  CoUninitialize(); ( d2 |- }, M# G6 D
  return 1 ; 2 l8 C! Z& ]+ }# p1 E. Z) ~
  // Program has failed.
6 N% U5 e8 B" ?) ?8 q  } : ]" o, Q4 f+ }# h* [* T
  if(pvNames)SafeArrayDestroy(pvNames);
- k) T. M: I% c9 j! H' f' l  } . Y9 `3 t' R& j
  if(pInstance)pInstance->Release(); & _  p4 h6 x3 h3 G5 L$ X9 N2 y
  - A( A' ]0 N& t8 N# x: L
  } # t4 A4 i2 {0 N# R5 p4 J
  // Cleanup
8 M# c' o; o% t4 L, h9 Y# y  // ======== 2 ^. k# W8 V0 Q
  pEnumerator->Release(); * Z% e$ d0 d0 ]6 v( c
  pSvc->Release();
! q9 r: n8 g1 z2 d9 a  p9 P  pLoc->Release();
$ O) Q, G# }* j# C  CoUninitialize();
& _4 ]1 c' Z0 Y: ?7 E  
) o' q% O) r2 [3 i7 R7 h" b  return 0; 7 l; x6 D: U: D
  // Program successfully completed.
, |/ N$ z% O& `2 U! d$ K5 `( Y  }
# q- O1 D2 b2 k8 _' Z$ ^  //-----------------------------------
% l) N7 g+ s$ A1 c' I' i! ]  
& W, P5 S8 d. I/ e4 y  对于怎么用BCB编, 感觉还容易一点,因为我在类型转换的时候碰到了一些问题,而在BCB中的Variant类做了比较好的封装, 具体代码可以 http://www.cppfans.com上找到.
8 H# i, D! v, S+ v4 Z+ R# z  
! ~( ]; h/ l6 \; g1 v5 `  void GetWmiInfo(TStrings *lpList, WideString wsClass)
8 f2 c# Q  |3 ^* T/ E$ m0 e  { 4 D: J6 n0 r4 v
  IWbemLocator *pWbemLocator = NULL; 1 k6 r- r/ t, D
  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)
3 U$ i. O) T  F) t- @  {
8 @# S" C4 B) \5 J& ^  IWbemServices *pWbemServices = NULL;
5 G9 e( Z2 [8 Q) \8 M+ r) z/ J  WideString wsNamespace = (L"root\cimv2"); 4 E; E( N+ k( ~0 {, `% S0 a
  if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK) * G) J$ }& H8 z; p9 D# W8 E6 w
  { " h4 c( a* D* N8 k1 o
  IEnumWbemClassObject *pEnumClassObject = NULL;
! e3 F! u7 R5 A  WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;
. |- J3 }( q" [  O0 @5 i2 |* N" L  if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK) 2 D" M3 i2 P5 q9 z( B1 R7 c
  { 0 E1 U9 R6 ]. [' E0 I4 [6 _3 j
  IWbemClassObject *pClassObject = NULL; - `7 E! e/ o2 D4 i  s
  ULONG uCount = 1, uReturned;
$ H: I" j/ g6 x2 N! s5 q  if(pEnumClassObject->Reset() == S_OK) ; t2 b/ r7 m0 V6 u7 i: y- ~
  {
4 E: E7 A& n% o5 v; z, L  int iEnumIdx = 0;
/ A2 p' q* W% S- {7 M7 k  while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK) ) X; [8 c* E2 T
  { # C2 W" G% P. C! l0 g
  lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------"); 7 K+ @1 A# l' g
  5 F) L; o9 Y, l, {' u
  SAFEARRAY *pvNames = NULL;
$ y; ?) w6 V- |, L* R  if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)
) ]# `2 H+ ]6 P3 ~2 w5 s  { 6 c9 F$ c: z% C3 ~: @" ~# p  |( ?
  long vbl, vbu; 9 }) X% P% h4 q7 h3 H* V
  SafeArrayGetLBound(pvNames, 1, &vbl); . i" C. T0 k) K4 j
  SafeArrayGetUBound(pvNames, 1, &vbu); : t; u0 Q  H8 _/ t9 Q; O
  for(long idx=vbl; idx<=vbu; idx++) 7 @) A, e% j& N# i( p
  {
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-6-18 12:19 , Processed in 0.019166 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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