文章来源:
http://wenku.baidu.com/view/64d5a356ad02de80d4d840a0.html
大家平时在用类似鲁大师之类软件的时候,会看到鲁大师之类的软件能够获取到PC机的硬件的详细信息,有时候自己在写软件的时候也需要获取PC硬件的详细信息,这个时候你会发现有的硬件信息通过系统的API函数无法获取到或者获取的不准确。所以这个时候就要通过WMI编程来获取硬件信息了。WMI是windows操作系统用来管理软件和硬件的核心。其它的不再多讲了,下面来看最主要的,通过WMI获取硬件信息。
整体来说,通过WMI获取计算机硬件信息有以下几个步骤
1、 用CoInitializeEx函数初始化COM参数。因为WMI中的类都是基于COM技术的。
2、 用CoInitializeSecurity函数初始化COM进程的安全,因为WMI的进程和应用程序进程不在同一个级别。
3、 获取IWbemServices指针,通过函数IWbemLocator::ConnectServer获取。
4、 通过CoSetProxyBlanket设置IWbemServices代理安全,使WMI服务可以模拟客户端。
5、 使用IWbemServices进行WMI查询,主要使用WQL语句。
6、 清理COM对象。
例子, 查询操作系统信息的一个例子
1 #include "stdafx.h"
2 #include <iostream>
3 using namespace std;
4 #include <comdef.h>
5 #include <Wbemidl.h>
6 # pragma comment(lib, "wbemuuid.lib")
7 int _tmain(int argc, _TCHAR* argv[])
8 {
9
10
11 HRESULT hres;
12
13 // Initialize COM.
14 hres = CoInitializeEx(0, COINIT_MULTITHREADED);
15 if (FAILED(hres))
16 {
17 cout << "Failed to initialize COM library. "
18 << "Error code = 0x"
19 << hex << hres << endl;
20 return 1; // Program has failed.
21 }
22
23 // Initialize
24 hres = CoInitializeSecurity(
25 NULL,
26 -1, // COM negotiates service
27 NULL, // Authentication services
28 NULL, // Reserved
29 RPC_C_AUTHN_LEVEL_DEFAULT, // authentication
30 RPC_C_IMP_LEVEL_IMPERSONATE, // Impersonation
31 NULL, // Authentication info
32 EOAC_NONE, // Additional capabilities
33 NULL // Reserved
34 );
35 if (FAILED(hres))
36 {
37 cout << "Failed to initialize security. "
38 << "Error code = 0x"
39 << hex << hres << endl;
40 CoUninitialize();
41 return 1; // Program has failed.
42 }
43
44 // Obtain the initial locator to Windows Management
45 // on a particular host computer.
46 IWbemLocator *pLoc = 0;
47
48 hres = CoCreateInstance(
49 CLSID_WbemLocator,
50 0,
51 CLSCTX_INPROC_SERVER,
52 IID_IWbemLocator, (LPVOID *) &pLoc);
53
54 if (FAILED(hres))
55 {
56 cout << "Failed to create IWbemLocator object. "
57 << "Error code = 0x"
58 << hex << hres << endl;
59 CoUninitialize();
60 return 1; // Program has failed.
61 }
62
63 IWbemServices *pSvc = 0;
64
65 // Connect to the root\cimv2 namespace with the
66 // current user and obtain pointer pSvc
67 // to make IWbemServices calls.
68
69 hres = pLoc->ConnectServer(
70
71 _bstr_t(L"ROOT\\CIMV2"), // WMI namespace
72 NULL, // User name
73 NULL, // User password
74 0, // Locale
75 NULL, // Security flags
76 0, // Authority
77 0, // Context object
78 &pSvc // IWbemServices proxy
79 );
80
81 if (FAILED(hres))
82 {
83 cout << "Could not connect. Error code = 0x"
84 << hex << hres << endl;
85 pLoc->Release();
86 CoUninitialize();
87 return 1; // Program has failed.
88 }
89
90 cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl;
91
92 // Set the IWbemServices proxy so that impersonation
93 // of the user (client) occurs.
94 hres = CoSetProxyBlanket(
95
96 pSvc, // the proxy to set
97 RPC_C_AUTHN_WINNT, // authentication service
98 RPC_C_AUTHZ_NONE, // authorization service
99 NULL, // Server principal name
100 RPC_C_AUTHN_LEVEL_CALL, // authentication level
101 RPC_C_IMP_LEVEL_IMPERSONATE, // impersonation level
102 NULL, // client identity
103 EOAC_NONE // proxy capabilities
104 );
105
106 if (FAILED(hres))
107 {
108 cout << "Could not set proxy blanket. Error code = 0x"
109 << hex << hres << endl;
110 pSvc->Release();
111 pLoc->Release();
112 CoUninitialize();
113 return 1; // Program has failed.
114 }
115
116 IEnumWbemClassObject* pEnumerator = NULL;
117 hres = pSvc->ExecQuery(
118 bstr_t("WQL"),
119 bstr_t("SELECT * FROM Win32_OperatingSystem"), //此处wql语句更改,实现不同的查询
120 WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
121 NULL,
122 &pEnumerator);
123
124 if (FAILED(hres))
125 {
126 cout << "Query for processes failed. "
127 << "Error code = 0x"
128 << hex << hres << endl;
129 pSvc->Release();
130 pLoc->Release();
131 CoUninitialize();
132 return 1; // Program has failed.
133 }
134 else
135 {
136 IWbemClassObject *pclsObj;
137 ULONG uReturn = 0;
138
139 while (pEnumerator)
140 {
141 hres = pEnumerator->Next(WBEM_INFINITE, 1,
142 &pclsObj, &uReturn);
143
144 if(0 == uReturn)
145 {
146 break;
147 }
148
149 VARIANT vtProp;
150
151 // Get the value of the Name property
152 hres = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);//此处把Name改成对应的要获取的属性值
153 wcout << "Manufacturer Name : " << vtProp.bstrVal << endl;
154 VariantClear(&vtProp);
155 }
156
157 }
158
159 // Cleanup
160 // ========
161
162 pSvc->Release();
163 pLoc->Release();
164 CoUninitialize();
165 return 0;
166 }
167