找回密码
 注册
查看: 5558|回复: 0

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

[复制链接]
发表于 2006-4-16 18:40:38 | 显示全部楼层 |阅读模式
    一直以来都没有用过WMI, 都是用的PDH来获取系统信息.感觉两者很些相似,都是类似于性能数据库,基本的一些什么硬件软件信息都可以比较全面的获得.只是用VC来调用相对比较繁杂,用VB和C#就方便多了.这些天到MSDN上找了些资料,总算大致搞清了一些编程思路.对于那些很想知道怎么获取诸如CPUID,硬盘ID,BIOS信息以及主板信息的人来说应该有些帮助吧.试着用MSDN的例子乱写了一通,以下是通过WMI获取BIOS的例子,不对之处还请指正 ^_^: # _6 W2 x& I: W& K8 b
  --------------------------------------------------------------------------------
. }. q# B* Y, b% X4 j3 C2 m8 ?- l  #define _WIN32_DCOM
1 r- @3 b: Q& m  #include <iostream> 1 U. s) Y5 B+ P$ `* T6 l, S
  using namespace std ;
% i3 a  ~' G9 g/ ~1 L  #include <windows.h> ! i: t+ k" Y4 S2 c
  #include <comdef.h>
/ U  U5 w8 N" f( I3 ~; x" \  #include <wbemcli.h>
9 F  l( i7 c' `& x2 r3 T  
: K/ E3 o# U) Y6 T* ^0 l  #pragma comment(lib, "Wbemuuid") 8 j! K7 I) w- J
    ?2 v# Y. W+ T# T# |/ k4 Y
  int main(int argc,char**argv)
% X* A6 f5 ~6 d% f% I& j  { . S! E. Y1 J* r$ m/ E. C  C& W9 c
  HRESULT hres ;
2 n) C% V' P8 R$ \& ^6 S! Q  9 g, b4 l. k5 l7 ?2 f
  // Initialize COM.
5 ?( I, O# x' y8 i0 `  hres=CoInitializeEx(0,COINIT_MULTITHREADED); 8 O$ u: H3 \6 ]$ i
  if(FAILED(hres))
5 o8 f* |. x  Z, i' B  { ; P- Q3 D0 b( u/ }
  cout<<"Failed to initialize COM library. Error code = 0x"
0 V. V7 b$ l% u* S2 |% l  <<hex<<hres<<endl ; ) ~6 U- U( X8 d3 L( _' A9 |6 P* @" f
  return 1 ;
& ]+ @$ I$ E. q0 T4 ~8 M  // Program has failed. . R" d$ c2 n3 a
  } ( U6 `5 i& c4 e; r- @5 \
  - b" _# d2 n9 l, m* |( ]# N$ a+ k* F0 K
  // Initialize & p7 n: I' o  N+ _* H6 M
  hres=CoInitializeSecurity( 9 M5 W. l6 `; H$ x) a; I/ n+ r9 s
  NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_DEFAULT,
; b) E. {& @. U  RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE,NULL);
+ Y, I+ @6 ^. y$ M+ |  
# G9 S% p4 w) X3 O; T  - P: ]" D9 u/ ]' |& [- q% Z: U- q
  if(FAILED(hres))
& d7 y, S2 C. c' r/ Z7 s" n  { " X, t0 y/ K: p7 V  {0 p  m: m; l' e
  cout<<"Failed to initialize security. Error code = 0x" - D9 }: D9 ?& t. j
  <<hex<<hres<<endl ;
  {1 P$ V! ?5 O' {7 y$ Q  CoUninitialize(); " b1 p  Q. B5 R0 _! i
  return 1 ;
- @2 ]9 _8 h/ m) R8 o1 a  // Program has failed. ( h+ N+ j8 g5 c: X' f( [0 V
  } . \7 X% O3 J- G0 B
  $ i6 B# A2 T  k0 B, L
  // Obtain the initial locator to Windows Management on a particular host computer.
6 y9 S* R; b% T! e3 N( M  IWbemLocator*pLoc=0 ; 4 R" b$ A3 x# O# C
  
7 G3 T' o6 u! d6 @5 n% e  hres=CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER, : x0 S* h) Q4 a8 {9 I; h. o9 P6 r
  IID_IWbemLocator,(LPVOID*)&pLoc); 5 Z/ m; j% h9 S: ~/ g
  # L: _' F" F+ E
  if(FAILED(hres)) 7 b1 L! _6 f5 N4 ~
  {
0 n* \1 X6 J0 }" y  cout<<"Failed to create IWbemLocator object. Err code = 0x"
. ]! _2 D$ @. @+ N  <<hex<<hres<<endl ;
3 H1 O$ c5 B$ W4 k9 P4 ?: t" k& u2 \  CoUninitialize(); . I* E$ d8 n* p6 T. D" M
  return 1 ;
6 o0 T' |' J. G% ?- N; X& j1 E  // Program has failed. ( [6 Q9 i3 S! w  W& Q
  }
5 v+ r8 @& o( M: h+ M* B' q( S  
9 D1 E7 F1 o2 K. t! Q; A) C, g  IWbemServices*pSvc=0 ; % n' e4 T, `7 n6 v  S+ {
  # w+ B. W1 U' ?5 J- Y
  // Connect to the rootcimv2 namespace with the current user and obtain pointer pSvc 3 u, ]6 ~" k6 {, N+ _
  // to make IWbemServices calls.
) a/ F2 e0 O, ^, ]: o  
  X2 Q* c( k: d# b2 D) M5 ]5 d6 Q  hres=pLoc->ConnectServer(_bstr_t(L"ROOT\CIMV2"),
% A9 Z" p! u) U" y7 v2 F. J8 G$ e  NULL,NULL,0,NULL,0,0,&pSvc);
% P: n  |3 n) {  E! G  
1 W) v* ^' E- i/ C& F' c$ ]) d: ?  if(FAILED(hres)) 7 o( u9 M% Y) s0 a% s& ~; L' F
  { 0 E# o. ^) w4 e" K8 s9 f
  cout<<"Could not connect. Error code = 0x"
/ D6 i9 A* Y) P  <<hex<<hres<<endl ; , t/ t+ C4 u! {& ^3 ~9 }. _
  pLoc->Release();
$ U6 Q! J: S( _1 o5 G5 O  CoUninitialize(); # d6 m% g" ?+ ]$ s/ l5 ?
  return 1 ;
! q# u3 K0 l1 m  // Program has failed. 3 u: g# m9 {" d8 w: B
  } " U; I3 Z+ q, m1 C" h+ q" @
  
  N+ z) z' B, z( v4 W  x  cout<<"Connected to WMI"<<endl ;
8 [8 M! ~$ `7 Q  X: b  : i0 C& @- E' r  ]
  // Set the IWbemServices proxy so that impersonation of the user (client) occurs. 4 R  _1 M6 ^' g0 g) v
  hres=CoSetProxyBlanket(pSvc,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,NULL,
: L6 x$ L1 U, X4 O4 b  RPC_C_AUTHN_LEVEL_CALL,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE);
$ ^6 i5 E; c( O: B  : y- |# ^1 D6 R! w: k
  if(FAILED(hres))
) g. }: p5 P3 v5 X8 y/ m  { * S* i8 L; ]) c% j( w
  cout<<"Could not set proxy blanket. Error code = 0x"
3 f+ _. G$ t& U+ ^* p! M5 b  <<hex<<hres<<endl ;
1 Q3 r% N  K% ?% H. B0 a- J  pSvc->Release(); 7 e; Q5 w9 g- L% A2 _
  pLoc->Release(); ! z+ t  T! E) A+ n* M
  CoUninitialize();
$ \3 i  V8 t% u6 i$ v3 d8 X  return 1 ; ; G/ v9 I9 }; C- o
  // Program has failed.
6 Q" }( \$ c9 V7 ?2 t6 {" b+ P  } % v' a( j- ?4 ?7 A3 E* a; S; w
  
+ W5 C: h1 Y+ t7 P" \  
+ T5 l7 Y. E! K9 d' T! ^  // Use the IWbemServices pointer to make requests of WMI. 9 @' _. v/ _- ?- _" E
  // Make requests here:
: r- j! }; D/ D+ Z( Y+ D- Z& t  ) I8 g& u" f$ u# T
  // For example, query for print queues that have more than 10 jobs
( y( V7 q# _4 s( e$ }. y  IEnumWbemClassObject*pEnumerator=NULL ; ) E* H) e' ^) {+ R8 Y
  hres=pSvc->ExecQuery(
9 M' s7 C" P$ u( m# E5 v* [, R. `% X  bstr_t("WQL"),
1 X: ^6 x4 q  t! u9 B  bstr_t("SELECT * from Win32_BIOS"),
' }$ @! a* c9 L* e4 y# K  WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,
1 H6 A" O: C9 f, e- |4 V  NULL, , B& _# J' E& f5 z9 v
  &pEnumerator); / _$ C( M' p: Y! r$ {8 G* d' O: ~
  
8 }& i% [, h% e  if(FAILED(hres))
# |& X" A& g+ i' X  {
7 y  H$ O0 b; L: ?  cout<<"Query for print queues failed. Error code = 0x"
% E1 r: [8 h3 r; {+ M  <<hex<<hres<<endl ;
/ N$ m2 A3 b# v. p( o; K/ j2 f) x% Y  pSvc->Release(); 4 e4 H) J4 n% I, D" c* s
  pLoc->Release();
$ y1 `$ q) k& V( t: p. {  CoUninitialize();
- I# j3 D# E  e+ x' q' E  return 1 ;
+ Y0 [- V" R' W8 p% p) S3 s2 M  // Program has failed. 0 e. x. S% A" V* D, n
  }   J! B. d0 D2 X: g8 j  A
  else 8 A' n; z% a3 b6 i) x
  {
: }/ G% o- B  ~) E7 d$ y: o- D9 w  IWbemClassObject*pInstance=NULL ;
" L$ ?3 v) v+ s' H  O  ULONG dwCount ; 9 Z  o: ~1 K0 F
  while(pEnumerator->Next( 1 X& I6 L) {1 O9 j$ G' D
  WBEM_INFINITE,
# |( Y5 r8 Q$ v. p  1,
. l' x" V# x1 f/ v' ~4 z  &pInstance,
: E" ~2 R/ F6 _0 A! C# w' Y  &dwCount)==S_OK) 2 W" J1 O* m' l
  { & Q9 z" L+ A( v1 s& e
  SAFEARRAY*pvNames=NULL ; 8 c; K8 `6 K. _" G, b2 Q
  if(pInstance->GetNames(NULL,WBEM_FLAG_ALWAYS|WBEM_MASK_CONDITION_ORIGIN,NULL,&pvNames)==S_OK)
& c: S1 F) `! c0 I- b' s- W  {
0 b$ U! M4 V* f9 I0 k# W  long vbl,vbu ; . j9 `7 P. ^1 w( f
  SafeArrayGetLBound(pvNames,1,&vbl); 6 e: h- I2 e' u# ^$ @: \  K; @
  SafeArrayGetUBound(pvNames,1,&vbu); 5 H+ m% `3 @' s0 T, H0 _1 ?
  for(long idx=vbl;idx<=vbu;idx++)
) _: I, i- R( P! V& G# e, I; W  {
  e; E- X* F8 T, T+ W' N/ l/ L1 e  long aidx=idx ;
7 ?* J6 t5 ]# o1 J# F  wchar_t *wsName=0 ;
6 X* ^- D  o5 j" H  VARIANT vValue ;
) x& J! V/ @2 S& f& a9 h% u  VariantInit(&vValue); 0 a* _' H  s9 Q: f
  
! Z( t3 q7 A) n  SafeArrayGetElement(pvNames,&aidx,&wsName);
* ]2 `! G" A9 h9 I$ g  
9 y# p1 _3 q6 V3 s8 P  BSTR bs=SysAllocString(wsName);
6 [+ |) a. w3 `8 D' @( }. I  hres=pInstance->Get(bs,0,&vValue,NULL,0); 5 Q+ @/ X1 B  f. P  Z8 z( h3 ?0 G
  SysFreeString(bs);
" N0 S! X' E4 s2 k8 c+ C  q  
1 D7 |$ g3 }4 j0 X  ( a6 m" \( ~; F' C: u0 ^& Y0 [
  if(SUCCEEDED(hres))
: ?) h, j' f$ T0 e3 y9 G2 `. y  { 4 U9 V. `+ T, \& F
  char szANSIString[MAX_PATH]; % v: r! G& {9 J: z/ d
  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,wsName,-1,
. c& g! C) G8 s, j% V  szANSIString,sizeof(szANSIString),NULL,NULL); 1 S" u8 X3 ^) d& j' x. p) K5 v
  1 \& G) }) d- ?, ]5 n0 P
  cout<<szANSIString<<" : " ; 5 s2 Q5 q* I! m8 a5 s0 f
  switch(vValue.vt)
% J8 W& R) Q/ g, A  { ( ^8 x# N6 M9 @" A3 I" A: Z. E9 h+ Z
  case VT_BSTR : 0 F+ f( |9 W$ J
  wprintf(L"%s",V_BSTR(&vValue)); $ `0 U: ~! s0 |! w$ ~9 B; z
  break ;
( H; B) k9 q6 j5 {  case VT_I2 :
, n/ c, A) M2 d; p0 p  wprintf(L"%d",V_I2(&vValue));   u; F: a: x) T8 T: L! S
  break ; # _: O6 ]7 Q) C9 Z) Q) {, l
  case VT_I4 :
: {1 F7 I3 ?0 R! x- H& x/ F  wprintf(L"%d",V_I4(&vValue));
, G) R/ ?4 K: v% G# v5 N  break ;
/ R) z9 ^& x% z7 A: S  case VT_BOOL : : [; b5 \! i4 n- ~9 \
  wprintf(L"%s",V_BOOL(&vValue)?L"TRUE""FALSE"); 0 w' D/ \" R1 q' e
  break ;
7 Z! [& g- p8 z8 `$ ]0 z  default: - a* g# g7 ^0 z5 X" Z7 B
  /*WCHAR tmp[100]; / I) ^: z' ]9 b% y$ h& z3 H
  wcscpy(tmp, V_BSTR(&vValue)); 4 h0 N* n; b5 x8 V! e# k+ u! c
  char tmp1[MAX_PATH];   \# e% \! B5 ^: n( G: T( k
  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,tmp,-1, # g( N7 @0 X! |4 O: A
  tmp1,sizeof(tmp1),NULL,NULL); 9 W- c- h1 N7 F4 q
  ; K- b/ K2 b8 I9 v- T  \
  cout<<tmp1;*/
2 c5 h5 K" ]% _/ H1 t4 Q/ h  break; 2 B' N+ H* Q! u' W6 b8 [* O" e
  } 0 Y8 ]  j- |, W- t; a
  cout<<endl ;
! F" k. w  M. j8 C1 q  B2 {9 ~  }
$ t* T. \8 s& g0 S  ! I9 l! _  B) b( ]& N
  SysFreeString(wsName); 7 ?( K2 t0 H* @2 P
  } : g: I0 W. n, g4 T9 C
  9 F* N8 ?; C5 N) g( g
  } 7 i/ e0 V$ v9 \$ T% G
  else 6 e4 S1 f0 n: G# k) v1 q
  {
3 W2 B: {% w! W% A, b2 a  cout<<"Query for print queues failed. Error code = 0x"
4 J6 e6 j9 H8 w) ]  <<hex<<hres<<endl ;
: X. V$ w/ t4 F/ `6 A  pSvc->Release(); , e, g7 Q) g) Z2 Q* i, D- t
  pLoc->Release(); 0 D1 y; s4 Y+ y# K- I7 R# \$ m3 R8 x
  CoUninitialize();
& J2 ~) e1 u" t- \) B  return 1 ;
8 t" N7 N2 v0 i" f( e  // Program has failed.
0 d  Z2 D0 d# O8 k  } / I5 J/ a$ G" r% E1 V# Y! t
  if(pvNames)SafeArrayDestroy(pvNames);
# @+ O7 d* n; q0 e: j  } 9 F" j5 _& i8 c8 n7 s8 }
  if(pInstance)pInstance->Release(); % ^: J/ k& o6 k9 ]$ g
  
, B2 E  T+ S* U% g7 T8 K3 i  } ( W8 B4 F7 V5 z7 {% n
  // Cleanup
! p  w+ |: \2 _1 W8 ?" q/ x  // ======== % E/ }+ F: d+ r* d6 @7 ]
  pEnumerator->Release();
  u2 }) A5 u& z1 x/ z" E3 B  pSvc->Release();
0 @2 H$ e) R: g2 d9 b  pLoc->Release();
- T. K; Q: _0 }3 j* v  CoUninitialize(); ) X$ L% |0 z# N6 I
  , b* g& R+ N9 I
  return 0;
* g9 _1 T% I" v. e8 f  S8 I) {7 }0 l' P& [  // Program successfully completed.
! k; g; u9 o6 G; x8 v3 T  } ' }8 C3 q% [: o
  //-----------------------------------6 X( h1 H: h0 }; {9 q7 G
  - H2 X4 N4 z0 K& o7 ^; |
  对于怎么用BCB编, 感觉还容易一点,因为我在类型转换的时候碰到了一些问题,而在BCB中的Variant类做了比较好的封装, 具体代码可以 http://www.cppfans.com上找到. + P4 L* s, S9 ^# n% P6 [
  
" G, y. s; |( `4 n7 d  void GetWmiInfo(TStrings *lpList, WideString wsClass)
) ^0 u  W4 N3 D# i# ]  {
3 }& {' v( q  ~  IWbemLocator *pWbemLocator = NULL;
& z" d6 y3 z: r2 I7 R1 i& K  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK) ! K. O% Z1 O3 n7 q
  {
0 I- W5 f4 @% E- q, Q5 ]  IWbemServices *pWbemServices = NULL;
  B! n% \: Z5 x$ `- ]" U  WideString wsNamespace = (L"root\cimv2"); 9 Q6 g: o6 j0 @, r* N4 |; @9 L! x
  if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK) 6 w( U0 U# u( ?
  { ) ]# g  B* @4 Y6 ^8 q4 E5 I
  IEnumWbemClassObject *pEnumClassObject = NULL;
3 N1 @6 ?% s, S/ V  WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;
- b1 k  e5 ]% l% a' K9 Q  if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)
8 S- M/ Z+ o7 H" }; p" e) M  {
' B7 p$ t) L! y8 o  IWbemClassObject *pClassObject = NULL;
: n5 f' x! y+ r( e: I; m1 R  ULONG uCount = 1, uReturned; . K+ p- W( Z. R4 q. T
  if(pEnumClassObject->Reset() == S_OK) 1 u/ \" G7 K6 C" ]5 i5 l7 ?! F$ R
  { . q6 V! r, a! s) t3 i. w3 {
  int iEnumIdx = 0; : n- l+ F& k; H% _% [" c7 ]. M" h
  while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK) 9 J  B! {3 h' r( y1 o# ~
  { 2 \; x( P+ [4 |5 |
  lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------"); ! d# n, ]  y8 x6 K
  
! @7 T  \1 z2 ]5 T( k+ Z& ]: B  SAFEARRAY *pvNames = NULL;
) p/ R8 t+ @  q; f- P# j  if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)
) W, E! W  a) H* I# s: R  {
5 y, t4 @; F! H6 X) h  long vbl, vbu; 4 c% y3 Z7 g9 ^" H
  SafeArrayGetLBound(pvNames, 1, &vbl);
# t8 t; W4 x/ J: [( k+ [- C  SafeArrayGetUBound(pvNames, 1, &vbu); & N& v$ X( r+ R, A, O/ K9 u
  for(long idx=vbl; idx<=vbu; idx++)
. a+ \' `& d8 r' p! P# W: C& V  {
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-10-1 22:02 , Processed in 0.018536 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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