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

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

[复制链接]
发表于 2006-4-16 18:40:38 | 显示全部楼层 |阅读模式
    一直以来都没有用过WMI, 都是用的PDH来获取系统信息.感觉两者很些相似,都是类似于性能数据库,基本的一些什么硬件软件信息都可以比较全面的获得.只是用VC来调用相对比较繁杂,用VB和C#就方便多了.这些天到MSDN上找了些资料,总算大致搞清了一些编程思路.对于那些很想知道怎么获取诸如CPUID,硬盘ID,BIOS信息以及主板信息的人来说应该有些帮助吧.试着用MSDN的例子乱写了一通,以下是通过WMI获取BIOS的例子,不对之处还请指正 ^_^: ) U* M5 z: Y0 R1 D
  --------------------------------------------------------------------------------
( Y: a. f# N! A  #define _WIN32_DCOM ' B% L& H1 h3 ]5 M* k2 Q
  #include <iostream>
3 W0 z  t- w( c& P" s0 [) P  using namespace std ;
' h6 T  ^, ]; g" s+ r  L4 u  #include <windows.h>
) a7 L) x' V$ t+ W" @4 y  #include <comdef.h>
+ k8 [! t# U$ W8 }5 {5 v  #include <wbemcli.h> 5 ?) \5 I! ^# n/ {  W% Y
  + d" K3 c; K* j# `; c
  #pragma comment(lib, "Wbemuuid") / L+ [8 b% ]1 o6 T
  
8 X  I4 s' r% k* w0 T  int main(int argc,char**argv) 4 [, ]4 \  H7 E; P
  {
$ `4 {+ ~5 h$ ]1 {6 i: s  HRESULT hres ;
3 p3 j9 t& [% m  
& E& F4 W! n& n  // Initialize COM.   J# @! P$ f+ L, y, }2 U; B& H! J
  hres=CoInitializeEx(0,COINIT_MULTITHREADED); . b; q  O4 h* @2 w; V
  if(FAILED(hres)) 8 s4 @! \0 n1 `
  {
: ~- n* k! y( x! p- S( g) b" o  cout<<"Failed to initialize COM library. Error code = 0x"
, N, k5 ^, u) h3 X* F& ]' t  <<hex<<hres<<endl ; - `9 }, M' E' Y' i7 Y
  return 1 ;
* V- C) D+ O2 b% L: v- \: B- k  // Program has failed.
9 G1 c  [% J2 p9 ~% A& O  }
( e; \6 ~' s& Z$ Y! t  
, @7 l% h' A# ]) G9 S% }  // Initialize
9 o* N" g4 f! W  u' M  hres=CoInitializeSecurity( & Y2 H2 ^; o8 T1 D) W! o% r6 e' R: U
  NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_DEFAULT, $ ^4 U+ V8 _$ p6 Z5 E& @8 f& ?
  RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE,NULL);
+ S4 X* T+ c  S! w# b  
/ g$ N6 T+ H0 d, p  2 z5 H' X: [. P; y
  if(FAILED(hres)) 7 Z. j2 x- ?6 P8 J; s2 j# Q+ }
  { 3 I8 x* s5 w, ~/ {
  cout<<"Failed to initialize security. Error code = 0x" $ B0 @5 _, `  O: c4 c8 [( h9 ?& W
  <<hex<<hres<<endl ;
! p; @( L2 n8 p" k  CoUninitialize(); " J* u5 z  I& M: Y4 W6 p; F
  return 1 ;
( j/ ^- X; z) }, k  // Program has failed. ( A' j5 J* X5 X4 G7 B" P" K
  }
4 K- [9 v% {5 c2 q  
5 v' j) o4 I, U  // Obtain the initial locator to Windows Management on a particular host computer. ( m7 d- F9 ]! w0 i! E# q* l
  IWbemLocator*pLoc=0 ;
- |! L! m: n3 ~! F& w  
1 d" Z8 ?' F: B6 n. D7 i  hres=CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER,
7 I6 ^3 a' C2 P- j0 V& t. |  IID_IWbemLocator,(LPVOID*)&pLoc); ' L% V# {! t' g7 {
  
  u1 p: ]% n( \8 \  if(FAILED(hres))
% l' n" ]6 U# b# m! Y" Z6 M  {
& b8 B" s8 Y4 R9 C8 ^. m) G  cout<<"Failed to create IWbemLocator object. Err code = 0x" * q7 d  n9 e5 X3 B
  <<hex<<hres<<endl ; 3 k/ i" x. j/ |6 g2 |4 X8 u
  CoUninitialize(); - q# _* M+ B1 Q/ k" O( n
  return 1 ;
4 O2 y8 S9 H3 u  // Program has failed. 5 s. ~% y! Q6 T& K
  } ! C" ~, n& U/ t; \5 Y  F) f1 z' _' y
  
; N3 p/ U* W0 ]5 M( B  IWbemServices*pSvc=0 ;
0 o4 b) ?. k% ^2 H: s  
9 x# M5 K% L" [8 ]  // Connect to the rootcimv2 namespace with the current user and obtain pointer pSvc 4 B+ \/ {0 u  B8 c( U% w# C
  // to make IWbemServices calls. & V. L5 N- m2 s; L
  5 R. b8 ]3 B4 {7 ]' \5 U1 [
  hres=pLoc->ConnectServer(_bstr_t(L"ROOT\CIMV2"),
7 ^* T/ y* X8 q7 T5 i/ f: }& g+ l5 z  NULL,NULL,0,NULL,0,0,&pSvc);
/ b9 [* B2 P; m& O$ ]+ {- u  
6 p5 L) J4 L$ f: x% o- k. L  if(FAILED(hres))
- Y) ^2 R) T( C0 G* p, a  {
0 r2 P" y* e0 Y5 ~  cout<<"Could not connect. Error code = 0x" 5 W. ^+ m5 L3 C0 i# F
  <<hex<<hres<<endl ; 4 U/ R. K+ w& D6 [
  pLoc->Release();
' h% j; K. c& U2 s7 H% f  CoUninitialize();
# k7 j8 W( A+ o5 L$ `  return 1 ;
+ P, w& x7 C6 n9 [) G* L5 t6 `6 X  // Program has failed.
/ e  J- `2 T' P& |8 p  } 5 J* T' Q+ E9 T  w
  
0 u4 w6 H. b; F  d3 ^& Q  cout<<"Connected to WMI"<<endl ;
( W# k! l0 F' X3 J. t  % w4 y/ [, w5 L0 p" N
  // Set the IWbemServices proxy so that impersonation of the user (client) occurs. 2 q+ ^0 }2 |+ k) T" ]9 o; v) S- y
  hres=CoSetProxyBlanket(pSvc,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,NULL, % v* p. t: k! e, I3 U! g4 X( z  R
  RPC_C_AUTHN_LEVEL_CALL,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE); 7 Y/ S2 p; ^5 s% p- I6 P  X3 h
  
% m% L' |7 k! v; F. R' H+ n  if(FAILED(hres))
5 Y* `3 l2 Y, h* [  Q+ l  {
9 F) q# [: h8 p. c4 \  cout<<"Could not set proxy blanket. Error code = 0x"
/ c( g% B, z4 s, T9 R; y# _2 ?  <<hex<<hres<<endl ; : O* X% _. b& J5 J7 K
  pSvc->Release(); : P9 Q0 d3 k6 b& }
  pLoc->Release();
  V  e6 k# M6 \7 F  CoUninitialize(); 6 R$ b. |1 L. x* ?7 m! X" O& o
  return 1 ; ' _9 @" T: y7 ?& k4 f* t, N
  // Program has failed. * {3 z" _! E; D9 A
  } # k4 E. z, [- u, T+ j3 ?
  6 x9 k+ P) l; `, R* f
  
% |; D7 I- |$ |: z5 [8 E3 W- ~1 s  a  // Use the IWbemServices pointer to make requests of WMI. ; j6 b1 c6 {( h& j# D, t( Z* Q
  // Make requests here: - n! Q* J7 \: Y/ u$ F* h
  ' w- ~) V6 M( y; G6 Y
  // For example, query for print queues that have more than 10 jobs
4 d7 Q/ W- }# f, v1 @' T# p: P  IEnumWbemClassObject*pEnumerator=NULL ;
1 c0 s7 F* v( h9 C2 O  hres=pSvc->ExecQuery(
# i9 c8 h0 D' {+ K) `$ B  bstr_t("WQL"), 0 G5 e, i' \2 N
  bstr_t("SELECT * from Win32_BIOS"), # h) G9 X( U' ]) A% c3 n* F
  WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,
  b, j; B; n3 c  NULL,
" q7 S, k+ F  Z/ T# `) q) V( s  &pEnumerator); : z. P# W; B: G/ ?0 l
  - r- ?& j! a1 z7 J# {7 ]3 o0 J, Z
  if(FAILED(hres)) 5 ?7 |( i  @9 Y% l# r
  { 4 Y5 k7 e" T5 I/ P% A
  cout<<"Query for print queues failed. Error code = 0x"
( p1 I. ]1 Q" z/ e# r  <<hex<<hres<<endl ;
4 S( `& w0 `2 i1 n  pSvc->Release();
, S7 q  k( ]6 f' n8 r  pLoc->Release();
! R+ W; U3 v; X5 s" D/ |. Y8 p" \  CoUninitialize();
/ n+ E9 I$ r6 P: W  return 1 ; 0 V, N: Y& I5 j' n: W
  // Program has failed.   P5 O, C3 ~% X- t& C- a
  }
. _, {' {2 o6 |; S: Q5 t  else ; G; j# v) u- e( X* P: c/ j
  {
# S$ }) I4 I6 m0 e7 m7 T1 T  IWbemClassObject*pInstance=NULL ;
( e- m8 t+ G; u1 W+ s  ULONG dwCount ; 0 j) F$ B' ~, j' L' @& y& R
  while(pEnumerator->Next( % b  n. ]! e; _( g" A5 M1 b
  WBEM_INFINITE, , T0 c3 s0 N# O* U5 R0 `
  1, 8 m" n7 ?2 {! H* u( C; |
  &pInstance, 6 y" }* G; C# M6 R
  &dwCount)==S_OK)
% J8 Z! \+ v; E% H+ E" o% j  {
0 e$ T! c/ k% x  K3 C3 [6 H  SAFEARRAY*pvNames=NULL ; 4 S) Y: T7 t. \1 b2 }( q$ W
  if(pInstance->GetNames(NULL,WBEM_FLAG_ALWAYS|WBEM_MASK_CONDITION_ORIGIN,NULL,&pvNames)==S_OK) 9 e0 @1 X+ l; B  j
  { : s( q; _( `( F3 C
  long vbl,vbu ;
6 _  a/ t" u  j/ o+ B* H  SafeArrayGetLBound(pvNames,1,&vbl); % k. g" D$ E8 g
  SafeArrayGetUBound(pvNames,1,&vbu); * ]! Z$ l5 P' Z# T4 \5 b+ T
  for(long idx=vbl;idx<=vbu;idx++) ! [( ^3 ?3 g# e8 _/ [4 p% x4 D
  { - K2 }* w! F6 }# b" a# A7 ~! U; }
  long aidx=idx ; : y# y8 t% k1 _
  wchar_t *wsName=0 ;
& t1 O# p. h' ?  VARIANT vValue ;
6 P; a: F7 U- D" `: f2 ?% B) D7 m  VariantInit(&vValue);
9 f3 Q5 _( x6 }- U9 T  
0 }# B% E6 @3 L  a  SafeArrayGetElement(pvNames,&aidx,&wsName);
# b" R, o3 o1 i  5 x% O, m! D% O6 n  b6 E( `
  BSTR bs=SysAllocString(wsName);
' X, J  z: N' P( I6 U  hres=pInstance->Get(bs,0,&vValue,NULL,0); 4 @2 T- x% n( U# Q( g) ~4 V
  SysFreeString(bs); 9 |1 C& n  c7 ~% A6 {( T
  
1 n1 [: A; t: u2 G9 B6 o# V  v: v    E7 i0 F+ |. d; R0 Q; L6 r
  if(SUCCEEDED(hres))
. h: c  A, ]! L- J9 U+ J9 K  {
  k' Q/ }. q! q! g+ P) B& W4 u! `  char szANSIString[MAX_PATH]; & [7 {8 M1 u% I& P( D7 M1 U
  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,wsName,-1, 9 i) I8 |; O2 L# ~* X  n
  szANSIString,sizeof(szANSIString),NULL,NULL);
) R( g# _& o# t. y# E- s  
# g5 ~8 ^& _8 [6 ?; |! n6 s; \$ K  cout<<szANSIString<<" : " ;
" j/ i7 s; @4 ?+ _5 I  switch(vValue.vt) ; E4 ^4 }5 U8 _& u& \8 Y
  {
0 L6 T% {3 e( X3 b* g0 N4 R  case VT_BSTR :
6 T' Q, X( K( ^* A8 O& R- Z  wprintf(L"%s",V_BSTR(&vValue)); : W2 F, p+ X: X0 H9 e9 }* v
  break ;
4 l2 `6 y/ \. ~: V  case VT_I2 :
: b: H- J) B4 g& J+ a  wprintf(L"%d",V_I2(&vValue)); $ l( n) D- X! J  x! i( C/ ]
  break ;
, k+ f4 h' x# P! Z+ X' J6 _& s! E  case VT_I4 : $ D5 e) Z5 R# _: u
  wprintf(L"%d",V_I4(&vValue)); 8 L2 t5 T" T" ?3 S
  break ;
3 X# F: x. K  J% x) u  case VT_BOOL : * ^6 N9 M8 @9 N  g0 o
  wprintf(L"%s",V_BOOL(&vValue)?L"TRUE""FALSE"); 1 |3 o0 N& q8 d/ @6 ]  I  Y, Q1 ~
  break ; 6 k# O* }+ G, Z3 R2 A2 P3 c& p: ]
  default: ! I" C$ T- {! O: L  T/ }3 q$ O/ F
  /*WCHAR tmp[100]; - m5 r) `8 J9 D
  wcscpy(tmp, V_BSTR(&vValue)); ! Z( ^! F. L1 i. a* g' w
  char tmp1[MAX_PATH]; % R) V, @0 r$ Y  B) X1 t
  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,tmp,-1,
) x1 c; V5 D) E' u" H! R  tmp1,sizeof(tmp1),NULL,NULL); # x3 ?. s$ B; }' n
  6 @6 M8 k/ E7 @
  cout<<tmp1;*/ ) x+ j$ U0 F& }  A, C
  break;
( j9 i# ~! s- j- M: `  } 8 x/ J% K  [; l' Q; l# w
  cout<<endl ;   j) c- A7 c# r7 j. N
  }
0 B, D' I, o9 {; |2 A9 |9 W4 N  
: e, C, v2 h6 k: b1 V; `. g6 k+ T  SysFreeString(wsName); . a% `' y0 H4 u% j
  } 7 Z! ], o# s2 j5 j# r
  + t1 Y- p8 u% X5 R
  } $ D: I& K9 q$ D& G% ?& V
  else
5 g9 F9 a  Z. p( [1 W  { ! W$ u; B0 Y& Q$ G; y, @' E5 h
  cout<<"Query for print queues failed. Error code = 0x"
& x3 ]' s7 o( P" f  <<hex<<hres<<endl ; ! H4 x1 H0 \- e! W
  pSvc->Release(); - `& c  ]8 g3 V' \$ S
  pLoc->Release(); 0 Y0 ^8 h( `) [$ s
  CoUninitialize(); 6 A6 w' {9 D1 _. j) e8 T
  return 1 ; * `) Z0 p) I  ]# _2 r5 \8 P0 X9 j
  // Program has failed.
( O0 P5 t6 _, S! p# w0 [  }
& f7 s7 a3 S4 @6 r. f2 _  if(pvNames)SafeArrayDestroy(pvNames);
' k3 H: ?1 |# j  } 2 M  k2 ~' {. I, q+ p) b5 B) B
  if(pInstance)pInstance->Release(); 3 \# ]! P* u( X/ C
  
! C; k$ a+ M) v  }
% G+ a, A+ z( D0 F, ~* p  // Cleanup
3 q6 i" S1 p) Q! x8 `  // ======== 6 P: l1 f; P2 t/ ?! M& Q2 n
  pEnumerator->Release();
; b% n  I/ P3 c  x+ o/ a  pSvc->Release();
6 Z9 _4 U4 `: b. z  pLoc->Release();
$ P; F, \+ A. T/ Z  B  CoUninitialize();
* o+ l8 ?( D/ u& n6 h0 K  
$ M3 y4 N  b4 \* \9 }  return 0;
. Q; {6 e/ P9 `  // Program successfully completed.
5 s3 L$ k: J1 y" S! s$ O0 B  }
% w& t1 g7 A) H9 R+ r; v& u  //-----------------------------------
9 u' v8 `9 X6 q- K* w- z/ y  % ^& X% I# Y& v$ `% K& R, v
  对于怎么用BCB编, 感觉还容易一点,因为我在类型转换的时候碰到了一些问题,而在BCB中的Variant类做了比较好的封装, 具体代码可以 http://www.cppfans.com上找到. ; k3 w2 i2 {3 w$ _8 ?
  : f; e/ o2 `6 h' f& N
  void GetWmiInfo(TStrings *lpList, WideString wsClass) 5 L/ e8 A( u1 R$ [
  {
+ k( C8 |: I3 L2 h  IWbemLocator *pWbemLocator = NULL; * k2 w0 j! f$ t" w9 ]0 U
  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK)
6 d& |5 y# v, ~. D8 ~$ ^( _" i( G7 Q  {
3 N5 [% a2 d, W" q# y5 y6 v2 Z  IWbemServices *pWbemServices = NULL; 7 Y% P8 |& g1 Q% \* Z7 c1 j
  WideString wsNamespace = (L"root\cimv2");   R! T$ p% X# w% b8 w& E3 j1 t
  if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)
+ q3 Z2 P% k$ n5 c: }  {   u! N% ]- e2 h/ M; N: e8 s
  IEnumWbemClassObject *pEnumClassObject = NULL; * p0 x9 R! B9 |$ U; v# s$ B: [9 u
  WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass;
4 R& d+ Y* n8 W4 v. v2 J+ h  if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK) / J$ `  L/ U! @5 d
  {
  q6 R% ^8 `9 {$ p% O  IWbemClassObject *pClassObject = NULL; - B6 k0 z6 _& f3 V
  ULONG uCount = 1, uReturned; . C# n4 d5 q2 i  y
  if(pEnumClassObject->Reset() == S_OK) ( ]6 J& ~( @' o# z
  { " P8 X: Y: b8 K6 ~  q
  int iEnumIdx = 0;
( O3 P) v, p" Z2 i+ l% M- k& F  while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
4 B) v1 K. k- Y! q: M3 y  { 7 B6 c# u" _; |9 d
  lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------"); 1 @' h. T7 H7 I8 F2 G$ S( J1 P
  
5 r* Z( t0 h  j7 v% l  SAFEARRAY *pvNames = NULL; / L  t9 O3 N  q  e5 S, E
  if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK)
; I* l! O/ }# q% a' d" z0 n; N6 p# ]  l  { ( D6 L1 T' \: M; n" n/ r# }/ t+ G) _
  long vbl, vbu;
) i. X% J  B3 B7 Z, O8 G: \/ y, Y' \5 @  SafeArrayGetLBound(pvNames, 1, &vbl); : m; I: M; D/ V/ J; k
  SafeArrayGetUBound(pvNames, 1, &vbu); ) q3 P4 Z- W. ^  h0 u! S8 l3 S
  for(long idx=vbl; idx<=vbu; idx++) # W2 k- W: w! e( J) X
  {
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2025-9-30 09:08 , Processed in 0.036025 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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