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

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

[复制链接]
发表于 2006-4-16 18:40:38 | 显示全部楼层 |阅读模式
    一直以来都没有用过WMI, 都是用的PDH来获取系统信息.感觉两者很些相似,都是类似于性能数据库,基本的一些什么硬件软件信息都可以比较全面的获得.只是用VC来调用相对比较繁杂,用VB和C#就方便多了.这些天到MSDN上找了些资料,总算大致搞清了一些编程思路.对于那些很想知道怎么获取诸如CPUID,硬盘ID,BIOS信息以及主板信息的人来说应该有些帮助吧.试着用MSDN的例子乱写了一通,以下是通过WMI获取BIOS的例子,不对之处还请指正 ^_^: . n+ S0 \$ K. G5 y8 [3 w
  --------------------------------------------------------------------------------
$ _& [; X. d: J" {* L3 R$ ?4 I3 \  #define _WIN32_DCOM ; Z% X- c3 p1 b/ x' b, u
  #include <iostream> 6 f8 X6 x: a( ^# T/ q4 }8 ^# M
  using namespace std ;
, X8 V* {( t/ F' ~/ H' |$ X9 _2 Y  #include <windows.h> : l4 }& D# B- w; E* P/ _# f
  #include <comdef.h> / T- b5 d- V; g* ^( G/ \
  #include <wbemcli.h> ) W) Y7 ], z% `. c* h. }  c
  
3 @0 _# M" z$ g# ?  #pragma comment(lib, "Wbemuuid") 2 K8 k) u2 V3 b( e4 N4 n' w" s! t5 u8 B
  
5 K2 @, C  r! U, E/ Y  int main(int argc,char**argv)
- A/ C3 u$ a# B4 z6 K, r  { 1 o& Z+ `1 z& ~( W( c! j$ J, q
  HRESULT hres ;
0 D* }6 E% B  g* j/ a: l  
1 D8 C6 T; Q: E  // Initialize COM.
' J6 w& I; m8 C2 M) y  hres=CoInitializeEx(0,COINIT_MULTITHREADED);
, ]% [: a2 I* G, _2 a  if(FAILED(hres))
6 d# }) b7 C* z2 f: T& N  { 2 H7 W; {& _7 M" D
  cout<<"Failed to initialize COM library. Error code = 0x" ( h$ V* t- e' u; S5 e( u" L
  <<hex<<hres<<endl ; 2 n( m: }; F& G- z9 B/ F& w
  return 1 ;
; Z+ ?8 C  T7 B: D" D/ O% L  // Program has failed.
: o7 W' v; E9 k6 c6 o, `  }
" i# T: H- }8 r4 z  
# q& j/ V* l* @# R5 z" P, k4 `+ `. G6 P  // Initialize
3 O& \( F0 E! L0 }  hres=CoInitializeSecurity( 2 ^9 h3 ?: O" A
  NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_DEFAULT,
! @: X6 G8 V9 F. k* S+ N! w* t  RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE,NULL);
( s) r# q& f4 G) Q+ g! S  " ?$ F5 @" u- w+ X
  # |8 }$ @2 u6 i! b$ Q% T0 J- y+ ~
  if(FAILED(hres)) : P8 n% D# [& F
  {
9 U% h! F, m; s6 z. L, Y  cout<<"Failed to initialize security. Error code = 0x" 9 n: l6 S( t0 l9 J' j) m% s! V
  <<hex<<hres<<endl ;
. O! k# g  {3 X# r  CoUninitialize(); 5 B: q. v5 b" R# [& e! G( s
  return 1 ; $ c5 Y6 n9 {  L% k6 l: J
  // Program has failed. 7 @4 X9 [9 q& W% L1 a. k" z5 ~
  }
! A* f7 S* g2 t3 }# _/ v  " ^; d; W( F8 i$ m( `
  // Obtain the initial locator to Windows Management on a particular host computer.
4 M4 k: ^- z# k2 M) t  IWbemLocator*pLoc=0 ;
/ V/ C2 T6 I6 N5 q* q/ `  0 G1 A5 C3 w8 x$ E& V
  hres=CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER, 4 @" z9 S; Z8 x
  IID_IWbemLocator,(LPVOID*)&pLoc);
5 v8 _' ?0 A+ a: ~; S8 v  4 |: @6 V% |$ q# t* Y% c4 ~
  if(FAILED(hres))
4 {$ ^* a. h' M) R7 e  {
& p$ @+ L- i9 y! o  cout<<"Failed to create IWbemLocator object. Err code = 0x"
" V! i8 T2 [( H7 X8 m% w8 i  <<hex<<hres<<endl ;
' Y. C2 i& X8 P$ U$ {/ u  CoUninitialize(); ' D! @2 c& g7 X7 A% K/ u
  return 1 ; 4 d: M& _8 ]+ c1 s7 H2 W
  // Program has failed.
3 _8 m* Z+ v. e8 r" w- M2 O  ^% X  } . \) y- H3 f% l
  + K! q$ b; T3 b/ f* o" U; {
  IWbemServices*pSvc=0 ; 1 `; K: |. |( t( ^' j- |
  $ u6 c2 S, p5 l
  // Connect to the rootcimv2 namespace with the current user and obtain pointer pSvc ' N4 I: k8 a$ C4 C5 s- ]
  // to make IWbemServices calls.
% P5 b1 ?% F( t) p  , U: ~, {6 W, F7 q% J
  hres=pLoc->ConnectServer(_bstr_t(L"ROOT\CIMV2"), - k7 W) |+ ]& }1 J
  NULL,NULL,0,NULL,0,0,&pSvc); " D: P% h5 Z% l
  6 u4 o% c, n2 h  h4 ~! v
  if(FAILED(hres)) $ w$ e' G  |& O1 S' E* z- ?: Z0 ?* z
  {
) V* v: l: x  \& @  T  cout<<"Could not connect. Error code = 0x"
' c7 O8 e$ N4 J8 G; t4 e4 ]  <<hex<<hres<<endl ; 2 p! k! O  i4 `4 @( L
  pLoc->Release(); ) L* k  e5 E8 i3 s% |3 B6 @
  CoUninitialize(); 5 }, B- H" X" [/ H  P
  return 1 ;
. \6 h  b( o+ I3 u  // Program has failed. % f" v( @: y9 T4 w! ~9 @
  } 6 k3 {% I* H9 \4 A' q* N4 @# r
  
% d: \3 j0 a8 k  cout<<"Connected to WMI"<<endl ;
2 e7 Y* c6 N# N- m1 j  
! h1 F6 ?, C# T+ K- S  g6 B  // Set the IWbemServices proxy so that impersonation of the user (client) occurs. ' X, P1 E/ X% O& j
  hres=CoSetProxyBlanket(pSvc,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,NULL,
( m3 Z  t2 M% v6 s& A0 E, l, x  RPC_C_AUTHN_LEVEL_CALL,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE);
  K4 z, x( u; I' Z- F6 J( S$ Y  
4 h: i7 z9 a% f  t' `1 ^  if(FAILED(hres)) 4 C) |; c7 O. Z) q/ o5 ]
  { 5 r! L8 k! t' ]6 ^. k: O
  cout<<"Could not set proxy blanket. Error code = 0x"
; x; {8 |5 I7 i% t' q5 s) v: D  <<hex<<hres<<endl ;
, a9 Q/ v/ y8 O( [; A0 w" H  pSvc->Release(); 7 L7 c/ c( W7 ~
  pLoc->Release(); ; p( b) j6 [0 N$ Y, l
  CoUninitialize(); * A, B6 f: R- i+ I! C
  return 1 ; ! I1 U: m! r2 C. p
  // Program has failed.
, c# ]* x; V+ n% w( m  }
- j; M: a2 _& d/ d. D  
5 \0 {6 j" ^. \8 v: b% e6 s  7 ]* E6 _' _5 v4 B" R3 R
  // Use the IWbemServices pointer to make requests of WMI. 8 p" V0 _3 I0 |! w* @/ A6 Y- f
  // Make requests here:
0 ?4 K5 U6 r$ C6 f; r  
' y; l0 X( F6 x: r6 T9 R  // For example, query for print queues that have more than 10 jobs
* E, a9 e& D$ m' P& b8 s( v  IEnumWbemClassObject*pEnumerator=NULL ;
- S9 c7 k5 i, \  hres=pSvc->ExecQuery( , M7 Q7 j' P8 p( X% g
  bstr_t("WQL"), % Y9 \( f* d7 S% s$ Q- x
  bstr_t("SELECT * from Win32_BIOS"), ) q$ {6 M8 J* c
  WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY, - Z7 f0 U6 Z0 e# Y0 S+ @; F
  NULL, $ b" g2 m! u$ d
  &pEnumerator); $ x0 V+ J% {/ @9 s$ R
  * t% p1 X2 b- v
  if(FAILED(hres))
- i# S  ~/ W3 ^+ v  ~. {  {
! t) W( V$ u" h: P, J. b/ U* r  cout<<"Query for print queues failed. Error code = 0x"
# `7 ]6 O& p0 r  <<hex<<hres<<endl ;
3 L6 M* u9 ?+ m6 {- Q6 S  pSvc->Release();
% z7 W/ M" V* c6 N/ w  pLoc->Release();
7 T. d1 O. J/ g% A$ q  CoUninitialize();
+ G; P. k; R' ~7 V. h% L! a( x  return 1 ;
4 P, q/ o7 h& T4 \* H  // Program has failed. 4 I: v" a% k5 H/ L4 ?0 C# I
  }
( F) E( y& h3 ~" B! e4 \& `, O  else 9 S/ s# {9 s3 R% g
  {
  m' j2 n$ v$ I4 U" B+ X, v+ Z! a  IWbemClassObject*pInstance=NULL ; 0 O- V  u; ^6 q: d6 O; U
  ULONG dwCount ;
4 V/ U/ M8 d1 O( F, N( c  while(pEnumerator->Next(
) ~! P* e  h0 L' \6 a/ s  WBEM_INFINITE,
5 h2 ]; o! H: k+ o% i* O  1,
8 q$ h: X1 r' L& E  &pInstance, 7 r% D+ y" K7 P! g6 M
  &dwCount)==S_OK) + Q" r3 [4 Z: M# c- c, r
  {
4 L, G3 l+ [2 X* u  O8 ~7 A& c  SAFEARRAY*pvNames=NULL ;
6 Y/ u* p2 z5 Q7 E) N) C  if(pInstance->GetNames(NULL,WBEM_FLAG_ALWAYS|WBEM_MASK_CONDITION_ORIGIN,NULL,&pvNames)==S_OK)
7 m" B8 ]. M2 \  \) a! P4 i4 v4 d  { ; X! j% N$ |+ u! Q8 Q; j4 {5 t
  long vbl,vbu ; ) i9 g! L( [5 q
  SafeArrayGetLBound(pvNames,1,&vbl);
4 N. ~* d9 m/ V4 y3 ^4 w  SafeArrayGetUBound(pvNames,1,&vbu); $ B4 X$ H4 y/ v3 \% r+ A
  for(long idx=vbl;idx<=vbu;idx++)
. ^  s9 C' V5 d6 C- |  { 5 q2 l# A% ]- X, Y7 i4 q5 Z
  long aidx=idx ;
# Y0 _& ]0 i+ _- R: H  wchar_t *wsName=0 ;
) p: Y! g* j/ S- k3 _  VARIANT vValue ; : Z; K2 F! \( _, L6 \# U0 x8 `7 z
  VariantInit(&vValue); 3 M. t3 z  a! X# |8 I6 ?
  * P0 h3 A, l' F3 e/ r
  SafeArrayGetElement(pvNames,&aidx,&wsName);
8 |  s' U6 ^9 P8 A  
  R$ H  N4 c* p  _  BSTR bs=SysAllocString(wsName);   h) Y8 b4 \1 I7 {+ N2 m7 o
  hres=pInstance->Get(bs,0,&vValue,NULL,0);
/ f) O8 t3 X7 R0 V  SysFreeString(bs);
: {$ f. Q& ]$ I& v  
9 i4 Q4 J/ H  ]/ t9 @  9 p& y! h: H; q5 P1 s! ]3 p/ @
  if(SUCCEEDED(hres))
7 I, u, S) \' U* q. r/ u$ C  { * R8 H2 I$ [% O" t9 x
  char szANSIString[MAX_PATH]; & }4 n+ |, x. y
  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,wsName,-1,
, p/ @4 U: ^' @5 X  szANSIString,sizeof(szANSIString),NULL,NULL);
* \% w8 z# K" j6 b3 ?, i3 g  
' K6 h$ s  @6 w7 g/ E9 A  cout<<szANSIString<<" : " ;
9 j% ~7 q2 E$ J2 o$ R3 J, n( _  switch(vValue.vt)
7 Y5 v0 I. j' c3 g8 ]) Z  {
+ o+ |5 y& C* d% b: P  case VT_BSTR : / N9 E  s1 j% R( A( \) E
  wprintf(L"%s",V_BSTR(&vValue));
! d' L& O, D2 G8 b- D0 y  break ;
0 U% D. @: m3 h* j" J  case VT_I2 : ' @  Y  r! o" S- l5 m% e( H1 z' F
  wprintf(L"%d",V_I2(&vValue));
6 k  b' G( ^" U, ^9 h/ J  break ;
$ O% o( L' p" C; B6 t  case VT_I4 :
$ ]9 [. b3 q9 [3 U+ ~# k4 p7 I  wprintf(L"%d",V_I4(&vValue));
& u0 U, N$ a! T, [; s  break ;
8 D& K6 }) @7 S1 Q2 p  case VT_BOOL :
8 W' y7 u5 M' A* R5 Y  wprintf(L"%s",V_BOOL(&vValue)?L"TRUE""FALSE"); 5 A; X8 S1 E  I. F& E: m8 I
  break ;
- ~# t3 v9 k" r' Y  default: 5 e8 {# ?( v* d8 S2 g6 j
  /*WCHAR tmp[100]; , m( N9 a- a- I7 m) W
  wcscpy(tmp, V_BSTR(&vValue)); , i7 @8 m1 i$ ]4 e- V4 W% Q2 f' N
  char tmp1[MAX_PATH]; * C9 L& g+ i0 y$ m, l0 B# }
  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,tmp,-1,
* a, |" l: y! C# _0 u6 G  tmp1,sizeof(tmp1),NULL,NULL);
* }  j8 Y7 z' j" j3 F) \$ |  
! @9 d, Y) w# E* F. f  cout<<tmp1;*/
, x, [9 A8 ~9 Q+ S  break;
/ X! [( b0 p) B. w" l  } 1 R( Q8 Y+ h; r, b1 H* n$ ?
  cout<<endl ;
' J6 _  r' T$ A' H) s( z  } , l# B& x1 @: C8 W4 s( i& e
  
$ B7 z+ B: }" W  SysFreeString(wsName);
2 G4 m& N! h) ]  } * g! k6 @$ T4 R/ i" q4 z4 p! N
  
' y6 x- u6 g. u% R2 p  } - {; D. K, ]1 ~# r: Z! I
  else
( q6 v) y! p- j. z7 l  J, i  {
3 Z6 t+ Q% n# m5 S# U" i  cout<<"Query for print queues failed. Error code = 0x"
; W7 [2 k" ?. s- L6 r6 f; ]& c  <<hex<<hres<<endl ; 4 b. |) }9 y# K3 G! c/ v6 Y
  pSvc->Release(); + p. [0 N2 P" |. x" q
  pLoc->Release();
* \7 m: J# ~. u7 F( U; i9 Y) h  CoUninitialize(); ; z+ P+ v% X5 U# s" ?
  return 1 ; 6 ~' J- i5 Z; A5 [
  // Program has failed. + t  V( k" q" i- {; A
  } & L& [; h: o# v+ `' c
  if(pvNames)SafeArrayDestroy(pvNames); / L  e6 m) [+ x7 ~+ t7 z
  } . ]3 u5 ?0 L! D; z
  if(pInstance)pInstance->Release();
$ C  F. D; I- v3 Q  
1 z9 E8 o3 s9 H  }
# Q1 ?/ q! V! \4 |  // Cleanup " C! H0 _6 V8 @# m* f/ c6 ]
  // ========
7 e7 [$ G" D, |( s7 g4 H6 u( }  pEnumerator->Release(); # R* [( d* s' l% T( x. [
  pSvc->Release();
! V3 w! j& z6 d: V9 f  pLoc->Release(); 4 Z& |8 Z. E( o( z4 G8 E  X
  CoUninitialize();
* M3 C" E; a. m  Q+ v  + K, f1 w* o- y3 u. T1 o
  return 0; + |6 S$ w# K- A- q
  // Program successfully completed.
3 a4 N; U8 f: b1 A6 i% S1 F# G  }
. ~! ^8 M7 u: T! t  //-----------------------------------, ^% x- e2 ]  r7 G0 T4 x4 I0 [
  
: k3 O8 B" q2 `, C  对于怎么用BCB编, 感觉还容易一点,因为我在类型转换的时候碰到了一些问题,而在BCB中的Variant类做了比较好的封装, 具体代码可以 http://www.cppfans.com上找到.
" Z8 S. P- j$ r7 X  a9 S" ~  ( F; `' v7 i! G3 }
  void GetWmiInfo(TStrings *lpList, WideString wsClass) $ T$ p$ ?& r( ?( T# Y- V9 ^& D
  {
% k" T; l4 e  n# l; Q  IWbemLocator *pWbemLocator = NULL;
7 ]( V! D8 U4 v& S- G1 j* J  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)
2 [7 L/ y) q$ S4 Q: ^) f  {
3 ~: D) m. G9 w$ m! Q" S. x2 x  IWbemServices *pWbemServices = NULL; ! \) J' I3 O8 q% O, _
  WideString wsNamespace = (L"root\cimv2");
& L- u& w# }6 P4 ?) v  if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK) & U* ?5 A) o" ^" }% g1 P. i) L% L$ t
  {
% ^& e0 J  t! R2 y  IEnumWbemClassObject *pEnumClassObject = NULL;
* a9 e; v. ^- H( P' @  WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;
" q' u. `9 e6 |, T) r# D  if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)
+ d8 R$ b( P  K8 t1 m6 l  { ) D6 R) Q4 o- Q/ l( Z* K0 c
  IWbemClassObject *pClassObject = NULL;
1 C) f3 x( ~/ B7 X1 ]$ ^2 c# Q/ A7 T  ULONG uCount = 1, uReturned;
" R; J1 U$ O- q) k8 n  H  g  if(pEnumClassObject->Reset() == S_OK) ' W" _4 e; \% p4 B2 ^  h
  {
) V% a8 o4 P* {% ]& V  int iEnumIdx = 0;
0 c9 W7 W- e! S% T+ e  while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
. m7 S# c/ k" U9 ^3 g  {
/ F2 `6 i" d4 D0 t3 a: v  lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------"); - ?2 k- X. x2 F' l: g$ a
  
* I4 _  [& {2 m4 m) t7 ^( t  SAFEARRAY *pvNames = NULL; / R( {; L, C. v' q9 g: ?
  if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK) # P4 |; W9 Q/ P* n* Z5 g" Z' u2 i
  {
8 c9 [' I' L6 z+ j7 `2 F  long vbl, vbu; , Y- U! ~3 N9 R' C( M5 a9 K
  SafeArrayGetLBound(pvNames, 1, &vbl);
7 o" L' W  Y* @7 k1 i/ ~  SafeArrayGetUBound(pvNames, 1, &vbu); . k) u3 H* D/ W/ _& }
  for(long idx=vbl; idx<=vbu; idx++)
) f$ C9 G9 m- A! I1 E" G6 O  {
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-6-19 14:32 , Processed in 0.014920 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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