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

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

[复制链接]
发表于 2006-4-16 18:40:38 | 显示全部楼层 |阅读模式
    一直以来都没有用过WMI, 都是用的PDH来获取系统信息.感觉两者很些相似,都是类似于性能数据库,基本的一些什么硬件软件信息都可以比较全面的获得.只是用VC来调用相对比较繁杂,用VB和C#就方便多了.这些天到MSDN上找了些资料,总算大致搞清了一些编程思路.对于那些很想知道怎么获取诸如CPUID,硬盘ID,BIOS信息以及主板信息的人来说应该有些帮助吧.试着用MSDN的例子乱写了一通,以下是通过WMI获取BIOS的例子,不对之处还请指正 ^_^: , o! Y# |/ `/ M. c3 B3 `6 c
  --------------------------------------------------------------------------------
$ {2 g7 f. x7 ?1 L8 k* I  #define _WIN32_DCOM 4 r% d3 s9 ~1 w7 s
  #include <iostream> ( C8 V7 w. }/ C& A' |
  using namespace std ; 7 p: M' |. i6 y' v; O- ^( x; D
  #include <windows.h>
) J% D' J6 Z3 d  #include <comdef.h> # s* l, W, I5 @' l; O/ n3 I
  #include <wbemcli.h>
$ @. x' G1 r; l4 \" h! D/ a: b+ X) h    A- t4 I  W2 h
  #pragma comment(lib, "Wbemuuid")
) F% f- O, ]+ l5 z$ p; Y  Q  ) v  f6 l4 Z  d
  int main(int argc,char**argv)
3 W6 \& I8 V0 K; M0 s. l6 Z  {
7 k+ n8 y( q+ Q6 }8 }  HRESULT hres ; ; @5 A! s, F7 E2 r6 J/ e" M0 W0 v0 _7 @
  
+ q6 h, q" l) m8 \- Q! G1 J: I" W  // Initialize COM.
9 w; n* ~1 U: U1 d5 f' V  hres=CoInitializeEx(0,COINIT_MULTITHREADED); . w/ Z$ u; H" O; j
  if(FAILED(hres))
4 ~6 }3 y9 q( b# u- {  {
- ?2 }+ T" e, c( |) p  cout<<"Failed to initialize COM library. Error code = 0x" " _# W2 x, G  e" t# C& V1 }
  <<hex<<hres<<endl ; 6 h% U& C7 D" a6 H5 }5 D9 q; d
  return 1 ; * g2 x( e, \! _# A
  // Program has failed.
# ?+ Y. A8 J7 P; B! o. t  }
- I6 A8 P) i/ X% g: E  
2 z5 w! g$ V3 Z  X  // Initialize 8 e$ H6 U: `* J
  hres=CoInitializeSecurity(
5 @3 U8 D2 ?1 n0 _7 \& i3 C9 }  NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_DEFAULT,
" `9 g" H* u. _% }) O# w; E  RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE,NULL);
2 x, Y3 \5 |2 @; g# Y4 E2 F( v; r  
' D! @6 H, C7 J$ h; f+ X1 ^  
( X( D4 C' Z0 _6 s: ?) J2 i8 n  if(FAILED(hres)) 7 l9 g( d( Y% x$ |7 H
  {
$ f7 S+ ~4 G& |  _. u, G% T" G7 ]  cout<<"Failed to initialize security. Error code = 0x"
; U) X: F3 }9 x* W6 F  <<hex<<hres<<endl ; 2 v* O* Z  e4 ^- |: J
  CoUninitialize();
5 z/ M4 Q7 I  h" a  return 1 ;
& d( s' E5 _3 B# m5 ~  // Program has failed.
5 k" }+ ]  V: _1 w, e+ k$ {  }
0 Z+ C( ~! _$ n: v$ F8 |  : r: E+ e/ r9 W) Z4 x
  // Obtain the initial locator to Windows Management on a particular host computer. $ F4 ~' r4 A* E" p" A
  IWbemLocator*pLoc=0 ;
, o" @6 {" _" }. v3 G- H8 ?  1 h% X, K' g( o1 `8 O- E
  hres=CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER, / C  J  E( w) l/ y
  IID_IWbemLocator,(LPVOID*)&pLoc);
% w; o( Q) K, ]  Q  x8 J' e  
. }/ p. Y3 c8 g% @6 p  if(FAILED(hres)) 4 A( w5 ^# c6 {; d, I
  { 0 Z& }8 y1 x7 S* c
  cout<<"Failed to create IWbemLocator object. Err code = 0x"
3 [; s: H: o$ a( L5 i9 S  <<hex<<hres<<endl ; " i; @8 S- t: I$ }8 Q0 D
  CoUninitialize();
* \! I2 a9 M. A, ~3 L  return 1 ; 5 ~* p) B6 G/ q8 s( t' N
  // Program has failed.
9 O( z) \$ A7 h  } 4 |1 m( e8 }, N) f
  
, s+ m/ x- V8 l% |  IWbemServices*pSvc=0 ;
) a& v# X6 ~$ g! K! W1 t4 M' l  
9 j# F$ \# z6 h( s' t  // Connect to the rootcimv2 namespace with the current user and obtain pointer pSvc
! E5 v$ s, X! ?( N9 R7 i; C; Z  // to make IWbemServices calls.
6 T) l$ i$ a5 _5 y7 h  
% m3 ^5 U& S8 P- Y: k  hres=pLoc->ConnectServer(_bstr_t(L"ROOT\CIMV2"), / J7 k/ ~4 i# T
  NULL,NULL,0,NULL,0,0,&pSvc); ) Z6 A, K: D4 f  C/ o) T
  
, v1 D8 y* s6 l2 x; T$ m9 j  if(FAILED(hres)) 2 j" R, {! A% A# Q, W
  {
, o! y) Y" S, x0 a+ _) X+ e  cout<<"Could not connect. Error code = 0x" : o' k" H3 y9 A/ e$ `+ `% T1 s
  <<hex<<hres<<endl ; ! y( p. I- L3 t
  pLoc->Release(); 4 P6 D$ {1 P! w) ~* h
  CoUninitialize();
  O$ C/ a6 h( `& r  return 1 ;
, w3 ~: c+ f; i4 A/ D# z  // Program has failed. ( _% l  }6 z/ u& n: D. `5 X* h3 K0 e
  }
/ ?. s% N" Q& h, C  8 }9 C" X9 `" K0 k
  cout<<"Connected to WMI"<<endl ; : k( i/ r" W& O1 w4 Z# d  _: C
  7 L8 Y# _# ^) b+ o
  // Set the IWbemServices proxy so that impersonation of the user (client) occurs.
$ T& Q; w% Z; L( m  hres=CoSetProxyBlanket(pSvc,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE,NULL, 7 q! t6 P7 B2 ~" g% j, A" h
  RPC_C_AUTHN_LEVEL_CALL,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE);
( b5 F6 S( P) z& L; A4 j  
0 O6 n7 U& Q7 y1 ^! ~  if(FAILED(hres)) ; A9 S0 C) L: G% R0 S" i
  { ! d9 a, W% Z1 N* j1 d. W, @; q; v/ u
  cout<<"Could not set proxy blanket. Error code = 0x"
: l6 e8 O) J# k  <<hex<<hres<<endl ;
3 V  J+ L) y/ a# e" ], c  pSvc->Release();
) V3 E3 l' W7 d' ^  pLoc->Release(); 4 }$ L  U8 L. a9 ]8 Q! `6 G. v2 I
  CoUninitialize(); 6 P/ ?' X$ k0 e& i7 C6 Q5 D% _4 K9 N
  return 1 ; 3 B9 [4 z5 p8 M1 w8 U. j2 O
  // Program has failed. , x, `/ E% e5 q! h. s
  }
* t  f$ Z, V! z& E* D  
% I8 ^0 [1 D, @) G. V$ T% H  d  4 x2 u2 D) K# t. y3 Z# j
  // Use the IWbemServices pointer to make requests of WMI. 8 F2 ~# j  m, j7 @  b
  // Make requests here:
4 k: ~- z/ |7 j9 {4 |* I  
7 M$ y5 T2 C# W; F0 a  // For example, query for print queues that have more than 10 jobs 1 ~5 V& O+ n3 Z. X
  IEnumWbemClassObject*pEnumerator=NULL ; 8 X: e; _4 }2 m+ v7 Z
  hres=pSvc->ExecQuery(
& ^9 ~" `. f: i! |* z# _0 z& D  bstr_t("WQL"), 7 O1 p% J( n0 I$ F7 Z2 o+ ]
  bstr_t("SELECT * from Win32_BIOS"), $ }! O% _7 j8 m# P1 ~- H) A, w
  WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY, $ z- ^6 A; q+ ~8 r
  NULL, 6 t; F# a; }' L% ~0 w
  &pEnumerator);   y) [0 }& |) B
  ) ~* [4 ^6 V1 R6 W- s  j8 f( J6 O' u
  if(FAILED(hres))
% _: h; _7 n- `; U- \  { - s2 e$ L7 P0 O
  cout<<"Query for print queues failed. Error code = 0x" # @& l/ F  S6 y* j, Z. H  u
  <<hex<<hres<<endl ;
) v) c: }2 I: U  pSvc->Release(); 4 s6 }6 Y0 S' |! X8 \0 F
  pLoc->Release(); ! x7 x1 y9 q- ]: ^$ f
  CoUninitialize(); / X) m% c' F5 h8 @! r& k: I7 I
  return 1 ;
/ X! P+ H$ [: G# ^; R3 z  // Program has failed.
% y( I: C  ]3 z1 Z1 Z  } 6 _; F! q8 `$ F: U7 k7 G# Q) R* F
  else   K7 E( q8 h# r" G6 F
  {
( E/ h8 _& G4 E  W* I/ j. w6 ?$ X  IWbemClassObject*pInstance=NULL ; * ]1 l" l  E" _9 G
  ULONG dwCount ;   ^9 i9 ?* E3 |+ d5 Q6 {$ T3 @5 W
  while(pEnumerator->Next( , O& d7 Q$ e3 w5 H
  WBEM_INFINITE, * t4 J. A4 T4 ~$ r' \5 y1 c$ ]
  1,
& Y9 Y( K: l5 R0 U) G5 h* ]- p  &pInstance,
: [$ U" V( I* ]& ^3 |2 y% \3 V  &dwCount)==S_OK)
+ S5 j1 r6 l- D$ l/ v  {
  z* Z7 E; G/ ~& U) c; l, z  SAFEARRAY*pvNames=NULL ;
2 w6 D  v$ {* ]  if(pInstance->GetNames(NULL,WBEM_FLAG_ALWAYS|WBEM_MASK_CONDITION_ORIGIN,NULL,&pvNames)==S_OK) ) c1 Y  M- \! F! d
  {
+ q+ A( b! i: M  long vbl,vbu ;
* @: Y% @. P. b8 K% j6 R  SafeArrayGetLBound(pvNames,1,&vbl); : U) B) N$ c* x1 G, D/ A( N  \
  SafeArrayGetUBound(pvNames,1,&vbu);
& O( ?0 H3 W: K* E$ \* b( T6 w  for(long idx=vbl;idx<=vbu;idx++)
/ a& |$ \+ ?# i9 D  {
/ Z. R- e, q9 R  long aidx=idx ; * K$ y& p" `2 u4 B2 i4 k! a2 o
  wchar_t *wsName=0 ; & a4 L  g. x; O* c9 a! w- \' f
  VARIANT vValue ; + T9 V6 N1 l' z" J
  VariantInit(&vValue);
; ]  E, d% D  D8 [  & @  P6 H& \2 L4 {& X. f
  SafeArrayGetElement(pvNames,&aidx,&wsName);
6 J3 G6 l; y0 ]  
2 ~" h. Y% I& a$ ?. r8 q: N1 s% A" r* S  BSTR bs=SysAllocString(wsName); $ c  c) o- |1 c5 o: _
  hres=pInstance->Get(bs,0,&vValue,NULL,0);
, w) c5 D2 ^. W8 ^& I  SysFreeString(bs); , a. b# _# \2 K8 n) W* U
  
$ y2 l* Y1 O1 o! Y/ w  v  
, {/ V% J1 I! |1 ]( _  if(SUCCEEDED(hres)) 8 M% e3 `* {, z) V! T+ c
  { / l+ \0 [5 v7 o, I
  char szANSIString[MAX_PATH];
. t  l: m' l# Y- g& X5 ]  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,wsName,-1, * n) p& J: g( o4 o5 Z$ X
  szANSIString,sizeof(szANSIString),NULL,NULL); 8 \. \- L# B; Y3 m
  6 F; V8 D1 V4 J3 e1 l4 ?
  cout<<szANSIString<<" : " ;
& k1 E: x9 E  B1 t! u' s" e, u- i  switch(vValue.vt) 7 M1 n; E- b. R1 g: p
  {
6 j" l; R  ?; K6 v  case VT_BSTR : % ?" n7 z" U4 N6 e: k/ ]' F
  wprintf(L"%s",V_BSTR(&vValue)); + B' S5 m' k9 F2 D; F
  break ;
  f/ d  }7 V, f; S  x  case VT_I2 :
: n8 K& q* F* m$ @7 x2 \  wprintf(L"%d",V_I2(&vValue)); 1 |$ z8 g* h& N, n" I4 V; B
  break ; # L) n$ z; j  U# k
  case VT_I4 :
( z; F, g' i# G) p7 u  wprintf(L"%d",V_I4(&vValue));
( {% I4 H0 l- A, g! c  break ;
" ~& s5 L) Q+ F/ L) B$ O  case VT_BOOL : 1 w9 P/ d3 r7 Y" g: E" n: i+ g
  wprintf(L"%s",V_BOOL(&vValue)?L"TRUE""FALSE");
, \$ D" p* J) C0 r* a0 J  break ; 3 h8 c* m4 U# ]
  default: % l  R6 E5 p0 n4 S! N" B
  /*WCHAR tmp[100];
$ d. ~7 {' V7 T' L  wcscpy(tmp, V_BSTR(&vValue));
2 \4 V% Y. T! G" a! D  char tmp1[MAX_PATH]; * i( T4 z5 X0 J* s& r
  WideCharToMultiByte(CP_ACP,WC_COMPOSITECHECK,tmp,-1,
. R/ B* V9 N  s  _5 @- Z5 u  c4 a- N  tmp1,sizeof(tmp1),NULL,NULL); 6 r' M7 @5 l. m; P+ v0 \
  
8 p% ^* k) X, u5 ]* j7 q  cout<<tmp1;*/
4 a4 v# n' t  k0 j* k6 D  break;
( o9 V( U6 p5 Y  }
. S# j/ y% ~. t* N* b  cout<<endl ;
/ ?# @2 H$ s0 x2 x5 N  }
# X( @% U! G9 j  : ?- i3 p2 b; |% {# P
  SysFreeString(wsName); ' |" S" i' l5 l$ S% P
  }
8 }9 v, ?: E: ~/ y1 O2 Q  
3 h$ G2 `) P0 ]7 Y  } 0 p2 F& |) f) [: |* z# {0 L
  else
; M- c0 S7 t# M6 [, q+ [3 X4 N  { " K, t# q: X; M' z# y! X; \
  cout<<"Query for print queues failed. Error code = 0x"
/ h' u7 ^# O/ D, J, Q" X  <<hex<<hres<<endl ;
4 q" t( i) s5 C  pSvc->Release(); : P8 }& x- k. e/ L. ^
  pLoc->Release(); / `6 x. H2 |1 e% s
  CoUninitialize(); . O. h( }, Y8 P7 r) H" P" S
  return 1 ; 0 Q8 y3 k0 L3 r! g; h+ P, t$ f
  // Program has failed.
* e- D2 L$ T1 Y* C' [) M! [  } 7 N6 C% n3 V% L- Y0 K
  if(pvNames)SafeArrayDestroy(pvNames);
& Q, k$ d, N8 h4 ~: \  } & E+ G/ S& X) Q, ]" s2 m, _. `5 T# I
  if(pInstance)pInstance->Release(); ) W5 {% l/ `$ G. o# R2 r1 ~
  % E( \! I$ ]  r8 s  W2 c
  } ) s( L3 o3 u5 T1 n0 @
  // Cleanup + K9 q% t  S5 G3 b  w5 R9 w2 ~' j+ ^
  // ========
7 N; E$ K$ i9 _8 ]: ~+ J  pEnumerator->Release(); 0 v" ]" y; R) G$ W& ?
  pSvc->Release(); ' r- u+ n1 f7 t3 d
  pLoc->Release();
8 X! a' B) y! h9 M  CoUninitialize(); 2 S4 b* w# E5 w2 F2 H1 J2 S
  
# ~9 {  b1 w4 K/ ~, e- J: Z, ]  return 0; $ N4 X9 s; Y! A0 ^  a( W
  // Program successfully completed. / J, m, ?1 y8 _7 Y2 B$ C( G
  }
3 _( K% c8 o* Q: `7 g  //-----------------------------------6 \; J2 V( G1 s: i
    [- v1 S- E% q  V* H6 T# y7 _
  对于怎么用BCB编, 感觉还容易一点,因为我在类型转换的时候碰到了一些问题,而在BCB中的Variant类做了比较好的封装, 具体代码可以 http://www.cppfans.com上找到.
; `  k! O! M3 {  
5 D. ?) x( ?( r6 H% r0 E  void GetWmiInfo(TStrings *lpList, WideString wsClass)
' R" ~! G( g! {+ I: K  { + {, L, P. T$ u* C  t+ b
  IWbemLocator *pWbemLocator = NULL;
( Z9 W( N7 M  }. I. W  I* o  if(CoCreateInstance(CLSID_WbemAdministrativeLocator, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pWbemLocator) == S_OK) 6 [" h+ @  Q- {. C
  { - Q6 q% x9 K; L" H6 S
  IWbemServices *pWbemServices = NULL; + c: I" v9 k6 J5 L8 L
  WideString wsNamespace = (L"root\cimv2");
, O0 K9 y; a, \  l. X( ]9 e9 S* X  if(pWbemLocator->ConnectServer(wsNamespace, NULL, NULL, NULL, 0, NULL, NULL, &pWbemServices) == S_OK) - R' f: A( w4 w' c. F' u/ a$ |
  {
* s. i( b) N5 p  IEnumWbemClassObject *pEnumClassObject = NULL; " z  k- m" X  K8 U
  WideString wsWQL=L"WQL", wsQuery=WideString(L"Select * from ")+wsClass; $ j" f9 ^3 D7 b9 k
  if(pWbemServices->ExecQuery(wsWQL, wsQuery, WBEM_FLAG_RETURN_IMMEDIATELY,NULL, &pEnumClassObject) == S_OK) 3 B1 j5 c( t/ x7 d  T! [5 f6 @
  { " Y; ?  d- X1 z# m
  IWbemClassObject *pClassObject = NULL;
  E8 L0 p. f" g- x- e  ULONG uCount = 1, uReturned;
0 U0 f  `& Q& F, g" U  i  F4 K  if(pEnumClassObject->Reset() == S_OK)
* h# I  O+ {* Q5 W9 n1 H- {  {
. d' k: t2 R: T8 X  int iEnumIdx = 0;
; Y! c* o3 j' }2 x  f  while(pEnumClassObject->Next(WBEM_INFINITE, uCount, &pClassObject, &uReturned) == S_OK)
9 K! T& X9 d) D/ C  P  {
& Z+ F) R3 L* ~9 _: G: |  lpList->Add("---------------- ["+IntToStr(iEnumIdx)+"] -----------------"); % C9 A" Q6 F' d  J8 D
  
5 e' C  g5 n) J* u; P$ l* J  SAFEARRAY *pvNames = NULL;
' _" Q' V/ X0 k5 b% u3 u4 l7 g" v8 O  if(pClassObject->GetNames(NULL, WBEM_FLAG_ALWAYS | WBEM_MASK_CONDITION_ORIGIN, NULL, &pvNames) == S_OK) * u$ z. V1 a( s4 f( O; Z1 I
  { * q1 u" V  l0 u. @1 c0 [
  long vbl, vbu;
1 d. x7 U0 F! E% f  SafeArrayGetLBound(pvNames, 1, &vbl); 3 E, Q/ r4 S  O( I) T. k6 ~
  SafeArrayGetUBound(pvNames, 1, &vbu);
& L1 }* o5 f! v4 E% J  for(long idx=vbl; idx<=vbu; idx++) ! c! Q: C3 o3 P5 o" W
  {
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2026-10-2 02:32 , Processed in 0.018573 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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