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

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

[复制链接]
发表于 2006-4-16 18:40:38 | 显示全部楼层 |阅读模式
    一直以来都没有用过WMI, 都是用的PDH来获取系统信息.感觉两者很些相似,都是类似于性能数据库,基本的一些什么硬件软件信息都可以比较全面的获得.只是用VC来调用相对比较繁杂,用VB和C#就方便多了.这些天到MSDN上找了些资料,总算大致搞清了一些编程思路.对于那些很想知道怎么获取诸如CPUID,硬盘ID,BIOS信息以及主板信息的人来说应该有些帮助吧.试着用MSDN的例子乱写了一通,以下是通过WMI获取BIOS的例子,不对之处还请指正 ^_^:
2 L0 u( w; o$ R) l0 a0 f  --------------------------------------------------------------------------------& o1 E4 D% ^! q! Q
  #define _WIN32_DCOM
6 U0 z! Y5 Q& @4 s, J  #include <iostream> 3 ]" T' t# v; I
  using namespace std ; 6 Q  Z- r* E* Y9 s  p
  #include <windows.h> 7 W$ J- [) c1 M
  #include <comdef.h> 6 n( C: @1 D( f. X' K8 P2 L$ z
  #include <wbemcli.h>
% U7 g# e/ u# I/ ]1 ]  
, E# e$ t8 x6 I4 w* R! \+ x8 r  #pragma comment(lib, "Wbemuuid") & ^/ s) I! j! N+ H/ ?3 b
  , P- z0 b6 Z6 A3 g
  int main(int argc,char**argv)
  c! ]" K6 |; A+ g$ [7 ^  {
9 Q2 P5 k$ V' f% d+ d; k3 I  HRESULT hres ;
! N* V! c3 T; V% K) F3 s9 U  % i* d" @% l- ^% M7 f) l
  // Initialize COM.
  Q9 U6 ~4 Z7 G; L* F, h4 L  q5 y  hres=CoInitializeEx(0,COINIT_MULTITHREADED);
: ~. V5 f8 e. D, Z  J3 U. m# ^  if(FAILED(hres)) 4 n5 W6 P9 y1 z7 c
  {
6 a6 B0 o+ x! w2 m8 \$ V$ {  cout<<"Failed to initialize COM library. Error code = 0x" " Z. k% C# _( }, E0 k4 N* H4 R8 P6 T
  <<hex<<hres<<endl ; , p, S4 r: F" J- w
  return 1 ; ) m# }1 X5 K2 _* T5 C$ k
  // Program has failed. 4 L" X4 ?! k5 U* C" r/ Y  y. F% j
  } 7 F* y/ j7 _7 U2 z
  
0 N. R* d6 D% {+ k& w: u: T: I  // Initialize " P! s+ ~. B" @% [6 z' e) g
  hres=CoInitializeSecurity( 1 w6 }5 I  F  i8 D$ r( D) d+ Y
  NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_DEFAULT, & P! n' G6 Q# c- `4 H8 n9 g# V
  RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE,NULL);
9 K  i0 m: h$ b) e' E" x; [1 s" N$ A    o/ ]5 `. A6 r$ ]6 o
  * V$ ?1 V+ k, p# Z6 C  G/ L1 a
  if(FAILED(hres)) " I3 C) a0 A- o6 D" x& l, R* [$ d
  {
% r1 Y* N1 t( Z+ C; O+ H  cout<<"Failed to initialize security. Error code = 0x"
6 r/ q  F. P; f6 }* N5 y! T  <<hex<<hres<<endl ; ) ?2 j7 \  i# h- L
  CoUninitialize();
1 R6 R2 `0 ]2 [' A- L$ S  return 1 ; 7 Z, q9 r6 e6 ?% |5 u0 y$ _& p
  // Program has failed.
# n* l2 s/ A$ M# y5 u+ \% K  }
% l/ K- d) c$ O1 F6 Y1 Z% G  
( B5 Q& g0 O* T  // Obtain the initial locator to Windows Management on a particular host computer. ( V% w7 w: M- Y9 a0 }) o: d& D
  IWbemLocator*pLoc=0 ;
- H1 ^9 h6 K% E8 g  & t+ R, C6 h8 U, {3 o
  hres=CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER,
* b4 o$ [: Y2 A0 @- `0 q3 I  IID_IWbemLocator,(LPVOID*)&pLoc); & y4 Y5 S$ u8 O) N1 P5 b
  
$ K/ z- @* d1 Y  if(FAILED(hres))
, i. t+ V: ~$ g7 A0 o  {
& b3 o/ d' v4 V/ G% Z1 i  cout<<"Failed to create IWbemLocator object. Err code = 0x"
/ ~6 W/ I9 M2 q6 ~8 F  <<hex<<hres<<endl ; ; m% D6 q" N2 N
  CoUninitialize(); ( m9 t6 D6 L. }( f, U/ \$ B
  return 1 ;   E: S6 q+ `% r( b" H: B
  // Program has failed. : n/ G; a; O5 t- \7 P& l
  } 8 j' ]5 s  g, F2 t$ @
  
, Y, k" F3 x, u" {  d' U  IWbemServices*pSvc=0 ; 7 a1 N9 S, ^7 |
  
; l0 D2 @. [8 D  // Connect to the rootcimv2 namespace with the current user and obtain pointer pSvc 1 p' j' @0 Q. f; b
  // to make IWbemServices calls. % j; h" L% b; `+ I. b3 M
  
9 H" m) d5 x, g! B9 Y. F0 j5 k  hres=pLoc->ConnectServer(_bstr_t(L"ROOT\CIMV2"),
5 c( Z% j5 b$ A  NULL,NULL,0,NULL,0,0,&pSvc);
5 \4 v) t$ a, q0 e9 ]  @$ l6 j% A; W  
! j7 B& z/ A$ D4 x$ s  i  if(FAILED(hres)) ; X5 ^5 E8 z& `$ B* _1 m# ^
  {
0 p" s5 K& Y& T1 J5 S/ J3 O+ K' i  cout<<"Could not connect. Error code = 0x"
5 B$ \6 P% [0 D+ ^1 Y8 n  <<hex<<hres<<endl ;
' s. L5 s1 o4 i# Y  pLoc->Release(); ( n7 t, e: Y* E2 V1 I; x
  CoUninitialize(); + s) B  J+ S7 l. J! w2 a
  return 1 ; - I( x' @3 }2 X
  // Program has failed. + ~" U; @; f( x- v
  } 0 z1 U. u5 [8 X: y1 k
  
. `; B: K5 \4 M3 J9 w  cout<<"Connected to WMI"<<endl ; * F: V* v8 ~; x8 L# ^% T1 C
  
1 |( ~, p' y2 J2 S* r  // Set the IWbemServices proxy so that impersonation of the user (client) occurs. 1 S- k( ~8 E) J
  hres=CoSetProxyBlanket(pSvc,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,NULL, ) [2 ?  V" d/ }4 {& O; `
  RPC_C_AUTHN_LEVEL_CALL,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE);
  e0 J5 |; l' n' d4 V1 j  ?  
  N4 c, `6 |  w# v' A4 L, o  if(FAILED(hres))
# m) m! b8 M. c( k8 j) _! `  { * S5 r- s' i$ l
  cout<<"Could not set proxy blanket. Error code = 0x"
0 b  M2 [) A- X  <<hex<<hres<<endl ; # t$ P: u% |( [
  pSvc->Release(); 8 ~# ?5 v! t( t2 T
  pLoc->Release();
. F, K! u/ T0 L( N0 |0 p6 v  CoUninitialize();
$ `$ k6 Q4 g9 _  f, @% D: C  return 1 ; 3 K4 G9 @* A$ k3 x7 @3 o4 `6 [: [
  // Program has failed.
8 l3 D& Z; r1 A4 g8 `0 V1 A$ F  } $ G8 L4 z8 R( A/ [7 L
  
/ N. l6 Z* B8 Q% |  Z% b! D  3 _. Y1 s8 ]0 H/ V
  // Use the IWbemServices pointer to make requests of WMI. 0 e) q9 y2 @1 V3 p
  // Make requests here:
% }: H$ o) z3 n% ]4 ]4 b# p  
+ @' S5 H; k+ {6 G  n  // For example, query for print queues that have more than 10 jobs
# F1 _8 j% s' u9 y1 m7 b1 V) a  IEnumWbemClassObject*pEnumerator=NULL ; , w5 r9 T! S" p* }4 B
  hres=pSvc->ExecQuery(
, W" m( q9 Y! ?  bstr_t("WQL"), ( X+ H3 v0 t) q5 @- @8 p9 X5 |
  bstr_t("SELECT * from Win32_BIOS"), 8 s+ g! ^; K6 [7 g0 Y& M% F
  WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,
+ z& `- \% n0 ?8 q  NULL,
$ _; f! W! H5 E7 _6 V  &pEnumerator);
" \6 O# b$ w: P- y& j  
" w* N" G. U) w5 L6 M  if(FAILED(hres)) 3 p# Z. U8 F6 v
  { & g5 n8 h* C8 J* u
  cout<<"Query for print queues failed. Error code = 0x"
0 A6 c! E  H4 L% p  <<hex<<hres<<endl ;
/ b, J1 A6 H- C  pSvc->Release();
* w5 u+ b, Q/ y' m: x& R0 j( q  B  pLoc->Release(); 0 w1 u( V( ^7 n+ W! f' m
  CoUninitialize(); # F8 A8 a8 f/ d7 r& y' k8 m: f3 `
  return 1 ;
( U) I/ x7 a3 O+ G0 G+ d( m4 n4 Q  // Program has failed.
6 u1 M# X4 X1 r' X) E9 R  } 0 p4 i7 M+ Q) r, n0 x  w% l# M
  else
: x& s  `7 S- G6 @% p, W  { 8 i7 |, E: \2 s/ E0 S2 K4 X* c
  IWbemClassObject*pInstance=NULL ; ' u7 A5 E$ c$ n& I/ D# p1 k* l
  ULONG dwCount ;
  ]1 n7 Q. ^* u/ b  while(pEnumerator->Next(
  i  s9 X' ~2 b2 z  }, ?  WBEM_INFINITE, 3 V& s  {. U8 U4 f1 ]
  1,
, m: U+ N# T0 q. y3 i5 O1 n  &pInstance,
0 ?$ }# g+ d5 _1 ?  &dwCount)==S_OK) / ?3 p' M" a% J
  { ! \. C1 p& V7 `& ]. ]- e) J; A5 i
  SAFEARRAY*pvNames=NULL ;
8 X( P* p3 r3 X8 |  if(pInstance->GetNames(NULL,WBEM_FLAG_ALWAYS|WBEM_MASK_CONDITION_ORIGIN,NULL,&pvNames)==S_OK)
5 h; {+ |' p' g  {
0 [  Q  M/ E! Q- J  long vbl,vbu ; ) _5 ^% t) R' i4 a) X
  SafeArrayGetLBound(pvNames,1,&vbl); 6 D# ^8 {8 m- o( o8 j* G2 _% `
  SafeArrayGetUBound(pvNames,1,&vbu); ; J6 Y) C2 e* c. v" W' J" M
  for(long idx=vbl;idx<=vbu;idx++) 4 I$ _/ |5 |% F8 ?4 b! n( U
  {
* I" [  H3 E, v+ z6 j% X. \  long aidx=idx ; 0 ?" e3 V* z" Y. D" D
  wchar_t *wsName=0 ; ; F9 L4 ?) l4 Y/ |. f0 J
  VARIANT vValue ;
# u" W3 q. m- H9 K  VariantInit(&vValue);
% Z; O3 z7 t0 \1 h" Q  % M; B4 _" Q- n9 @# K
  SafeArrayGetElement(pvNames,&aidx,&wsName);
! D, c' h5 O6 I2 V: k  
1 ]7 ?8 `+ [8 q  X, V" W4 f  I  BSTR bs=SysAllocString(wsName);
9 p) i& G% G7 F: q& P  hres=pInstance->Get(bs,0,&vValue,NULL,0);
' \4 [, {- B& O- t( b  SysFreeString(bs);
2 o7 N2 |3 n0 I2 I  + v9 p9 y! {6 }8 z
  
" B, P9 V5 \( _; s% [6 [' d; E' P  if(SUCCEEDED(hres)) 0 r& `4 F! Y9 O7 M- U
  {
' M5 X3 Y( o2 F7 O- {) E  char szANSIString[MAX_PATH];
, @; |  a8 G7 E! b  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,wsName,-1, ; g9 K' w( k8 L: ]6 [5 R9 {( p
  szANSIString,sizeof(szANSIString),NULL,NULL); 2 t) n9 H* \: k1 ]
  
1 {4 u" v$ `: C2 ], S3 D7 m  cout<<szANSIString<<" : " ;
+ ^; k1 W9 h& s( D/ B! _  switch(vValue.vt)
4 p( Y6 M" K/ }; A  t6 `  {
( m5 r4 z+ {$ T3 k6 o* q  n  case VT_BSTR :
: n. s! U, Y9 A, b* G) W& P  wprintf(L"%s",V_BSTR(&vValue));
9 [4 O$ R# j2 b) Y: X; A/ \  break ;   O4 i+ ?  m2 B7 _' Q7 E
  case VT_I2 :
, o; D2 ?3 P  Z, m. V  wprintf(L"%d",V_I2(&vValue));
0 h+ K( R, I  X/ Z4 M  break ;
8 b2 M; U0 T3 W  case VT_I4 :
7 q* h# a2 m5 J% M5 F3 ^  wprintf(L"%d",V_I4(&vValue));
: Y9 ~1 Q% T; a, Y& L  break ; ' R! [3 h2 f( F
  case VT_BOOL :
1 D0 Z% D6 c6 C/ t% w  wprintf(L"%s",V_BOOL(&vValue)?L"TRUE""FALSE");
5 a8 x& ]0 H- _' K9 A! ?  break ; # X* X$ x" O' l2 ?: q5 q' W
  default: 3 Q3 ~, y8 Q/ {6 y: {/ Q  i) i
  /*WCHAR tmp[100];
* H8 H% X  T( ~$ L+ ~  wcscpy(tmp, V_BSTR(&vValue));
. \2 [8 f8 J+ r, H8 F; P  char tmp1[MAX_PATH];
7 I& f' f& y  u5 w  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,tmp,-1,
% u0 d( n" G$ o& F. C  tmp1,sizeof(tmp1),NULL,NULL); ' D& F$ ^7 [& m8 ~5 C
  
. x. s+ J3 I  ?  cout<<tmp1;*/ * H. ?: D$ A/ v+ C7 T& V
  break;
3 o9 ?- Y) E8 o  } " N( M8 L: Z* l  \* ^) u
  cout<<endl ;
  n- W; n0 X3 L8 x# `1 Z# w7 Y/ N$ d. q  }
# j, d0 O4 [" O  i; |& L9 g  
6 v. x/ o" @! N6 y0 i; R$ l  SysFreeString(wsName); ) s3 I, I; d3 b/ l1 M
  } # V- _7 b$ i  }0 W  Z8 l" y
  
. X& G$ P) D0 K5 g! r8 q  }
4 E6 O) U: `8 X" r: `# ]' i8 t9 M  else
7 z1 [" b# U/ _2 ?* }4 X  {
& H- u' G" V0 Q* U! u  cout<<"Query for print queues failed. Error code = 0x" " D3 q$ Y% \& C! y: H, w
  <<hex<<hres<<endl ;
# ^* G$ e( w( g: B/ ?, t  pSvc->Release(); 9 a% x. U4 t1 Q5 f' e% d4 P! S2 i
  pLoc->Release();   ]6 @4 I7 O( H: X9 j
  CoUninitialize(); , J+ c( k8 w7 o8 k  U% N5 ?8 U
  return 1 ; 9 `2 a7 z. y; F
  // Program has failed.
% A1 C/ [, y6 A5 R2 k2 B7 N  }
5 v! C- G# O4 ^6 r  if(pvNames)SafeArrayDestroy(pvNames);
2 j# t, f# d7 x# A6 L  } 9 w7 q. _& c' M- c6 B2 z1 N, l1 H
  if(pInstance)pInstance->Release();
& g3 ^, h9 e" H. Q  
; I- Q- s( v4 k! s  }
; T. I/ m+ H; K$ ]  // Cleanup
! M/ T/ \0 T" M% Q& w  // ========
& y* X) T% f! U. V1 V4 h  b  pEnumerator->Release(); ( q- F. m1 u4 e+ \# T1 k+ h
  pSvc->Release();   A, `/ H  T  H9 X% ]# D
  pLoc->Release(); % q) w3 a7 o% o2 m. d% W9 _
  CoUninitialize();
, L" V0 U# g, I9 m+ t. U  3 ^9 p* o" t# N! \9 Z; k9 T
  return 0;
6 R) A/ @. |, o3 @& ~  // Program successfully completed.
# B* D0 I$ }7 D1 M" `& M  }
* K5 v3 K" M- A. W0 S* ?; y  //-----------------------------------. q9 _+ i9 R- V: k: @7 z4 l! o& r- L/ Z
  " _( }" i& F  b- g- N) H+ P$ M
  对于怎么用BCB编, 感觉还容易一点,因为我在类型转换的时候碰到了一些问题,而在BCB中的Variant类做了比较好的封装, 具体代码可以 http://www.cppfans.com上找到. ! }7 Z3 d$ ?, t$ {# ]4 u4 a/ ~. Y
  + I/ i. y/ ~- b1 ?! u7 Q3 n: N% x1 A
  void GetWmiInfo(TStrings *lpList, WideString wsClass)
' V" U  y8 k  ^5 I  { ) y1 V4 ^( H- {! R6 f
  IWbemLocator *pWbemLocator = NULL; ( T# z& \( Y$ S8 K$ Z; ]( |% a( w0 x  e' Y
  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK) 5 S3 F" u9 A1 ^" G% }
  { 7 @) b/ V0 K3 Y3 e% b
  IWbemServices *pWbemServices = NULL; ( C8 e  _) S% X; I; {! n
  WideString wsNamespace = (L"root\cimv2"); " H3 i$ C3 a9 n- l
  if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK)
& E/ ^5 z) H: ^. e4 \0 e3 f  {
" @! g0 u' G1 |7 B+ q" Y  IEnumWbemClassObject *pEnumClassObject = NULL; , C# `5 [0 H: }" e$ F- C- K3 L. c
  WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass; 2 v* J2 q0 w9 i9 [
  if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK)
! P$ c% p. e) Y7 \4 ]  { 0 e1 Q5 h' [, E
  IWbemClassObject *pClassObject = NULL; 1 F! ?* a, |! n9 d6 {) e" ]
  ULONG uCount = 1, uReturned; ! ]( J* j9 T/ h* z* ]
  if(pEnumClassObject->Reset() == S_OK) + x( u5 Q) O8 U0 x; d. {
  {
+ R/ v8 F# c, H3 ?7 j- w, F  int iEnumIdx = 0; & q: d3 K* d& R) `+ \9 o7 E( }
  while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
: i. o# ^& x( u+ h7 F9 X4 y" n' E/ _  {
, S/ |9 k0 E; x2 ?- r7 K5 O  lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------");
& R' _9 Y4 J( a7 x, N  2 W( M: J8 i0 R1 k  V" |
  SAFEARRAY *pvNames = NULL; / u% j' \% [2 w  m6 Z6 \. d2 S; T
  if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK) # o" H' {0 X4 S
  {
% O& C" @" a% C5 n9 X6 |* P& Z  long vbl, vbu;
1 T* I1 o6 l6 M  SafeArrayGetLBound(pvNames, 1, &vbl);   R7 Y1 E% e+ Z2 A, g" V
  SafeArrayGetUBound(pvNames, 1, &vbu);
* Y2 o* @* R- U7 Q% Q' K  for(long idx=vbl; idx<=vbu; idx++)
9 N* ~5 P0 |/ D) b$ J$ d% E  {
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-10-1 20:47 , Processed in 0.030210 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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