使用WMI编程获取主机硬件信息(CPU_ID,硬盘、主板、BIOS序列号,Mac地址)

最近在公司实习,有个应用需要获取windows主机的一些硬件信息,在网上查阅了一些资料,大部分都是使用WMI编程来实现的。

因此小菜鸟自己也用WMI实现了一下,封装为函数GetUserInfo(),具体代码如下:

头文件UserInfo.h:

 1 #pragma once 
 2 #include "stdafx.h"
 3 #define _WIN32_DCOM
 4 #include <comdef.h>
 5 #include <Wbemidl.h>
 6 # pragma comment(lib, "wbemuuid.lib")
 7 using namespace std;
 8 
 9 typedef struct UserInfo_t
10 {
11     char CpuID[20];                    //CPU序列号
12     char BaseBoardID[256];         //主板ID
13     char SystemDiskID[256];        //系统所在硬盘的序列号
14     char BIOSID[20];                   //BIOS序列号
15     char MacAddress[20];             //MAC地址
16 }UserInfo;
17 
18 int GetUserInfo(UserInfo &info);
View Code

源代码GetUerInfo.cpp:

  1 #include "UserInfo.h"
  2 #include <windows.h>
  3 
  4 void Trims(char* data)           //去掉字符串中的空格
  5 {
  6     int i=-1,j=0;
  7     int ch = ' ';
  8 
  9     while(data[++i] != '\0')
 10     {
 11         if(data[i] != ch)
 12         {
 13             data[j++] = data[i];
 14         }
 15     }
 16     data[j] = '\0';
 17 }
 18 
 19 int GetUserInfo(UserInfo &info)
 20 {
 21     HRESULT hres;
 22     memset(&info,0x00,sizeof(UserInfo));
 23     
 24     CoUninitialize();
 25     hres =  CoInitializeEx(0, COINIT_MULTITHREADED);   //第二个参数设置当前线程的并发模式为多线程
 26     //hres =  CoInitializeEx(0,COINIT_APARTMENTTHREADED);  //并发模式为单线程(即只能在单线程函数中调用GetUserInfo())
 27     if (FAILED(hres))
 28     {
 29         return -1;                  
 30     }
 31     hres =  CoInitializeSecurity(
 32         NULL, 
 33         -1,                          
 34         NULL,                        
 35         NULL,                        
 36         RPC_C_AUTHN_LEVEL_DEFAULT,   
 37         RPC_C_IMP_LEVEL_IMPERSONATE, 
 38         NULL,                        
 39         EOAC_NONE,                   
 40         NULL                         
 41         );
 42     if (FAILED(hres))
 43     {
 44         CoUninitialize();
 45         return -2;                 
 46     }
 47     IWbemLocator *pLoc = NULL;
 48     hres = CoCreateInstance(
 49         CLSID_WbemLocator,             
 50         0, 
 51         CLSCTX_INPROC_SERVER, 
 52         IID_IWbemLocator, (LPVOID *) &pLoc);
 53     if (FAILED(hres))
 54     {
 55         CoUninitialize();
 56         return -3;    
 57     }
 58     IWbemServices *pSvc = NULL;
 59     hres = pLoc->ConnectServer(
 60         _bstr_t(L"ROOT\\CIMV2"), 
 61         NULL,                    
 62         NULL,                    
 63         0,                       
 64         NULL,                    
 65         0,                       
 66         0,                       
 67         &pSvc                    
 68         );
 69     if (FAILED(hres))
 70     {
 71         pLoc->Release();     
 72         CoUninitialize();
 73         return -4;                
 74     }
 75     hres = CoSetProxyBlanket(
 76         pSvc,                       
 77         RPC_C_AUTHN_WINNT,           
 78         RPC_C_AUTHZ_NONE,            
 79         NULL,                            
 80         RPC_C_AUTHN_LEVEL_CALL,      
 81         RPC_C_IMP_LEVEL_IMPERSONATE, 
 82         NULL,                        
 83         EOAC_NONE                    
 84         );
 85     if (FAILED(hres))
 86     {
 87         pSvc->Release();
 88         pLoc->Release();     
 89         CoUninitialize();
 90         return -5;              
 91     }
 92 
 93     //获取CPU序列号
 94     IEnumWbemClassObject* pEnumerator = NULL;
 95     hres = pSvc->ExecQuery(
 96         bstr_t("WQL"), 
 97         bstr_t("SELECT * FROM win32_Processor"),
 98         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
 99         NULL,
100         &pEnumerator);
101     if (FAILED(hres))
102     {
103         pSvc->Release();
104         pLoc->Release();
105         CoUninitialize();
106         return -6;              
107     }
108     IWbemClassObject *pclsObj;
109     ULONG uReturn = 0;
110     while (pEnumerator)
111     {
112         HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
113         if(0 == uReturn)
114         {
115             break;
116         }
117         VARIANT vtProp;
118         hr = pclsObj->Get(L"ProcessorId", 0, &vtProp, 0, 0);  
119         wcstombs(info.CpuID,vtProp.bstrVal,18);
120         VariantClear(&vtProp);
121         pclsObj->Release();
122     }
123     
124     //获取主板ID
125     pEnumerator->Release();
126         pEnumerator=NULL;
127         hres = pSvc->ExecQuery(
128         bstr_t("WQL"),
129         bstr_t("SELECT * FROM Win32_BaseBoard"),
130         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
131         NULL,
132         &pEnumerator);
133         if (FAILED(hres))
134         {
135             pSvc->Release();
136             pLoc->Release();
137             CoUninitialize();
138             return -7;              
139         }
140         while (pEnumerator)
141         {
142             HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
143             if(0 == uReturn)
144             {
145                 break;
146             }
147             VARIANT vtProp;
148             hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0); 
149         wcstombs(info.BaseBoardID,vtProp.bstrVal,20);
150             VariantClear(&vtProp);
151             pclsObj->Release();    
152         } 
153     
154     //获取系统所在硬盘的ID
155     int diskIndex = 0;
156     pEnumerator->Release();
157         pEnumerator=NULL;
158         hres = pSvc->ExecQuery(
159             bstr_t("WQL"),
160             bstr_t("SELECT * FROM Win32_DiskPartition WHERE Bootable = TRUE"),  //查找启动盘
161             WBEM_FLAG_FORWARD_ONLY |                        WBEM_FLAG_RETURN_IMMEDIATELY,
162             NULL,
163             &pEnumerator);
164         if (FAILED(hres))
165         {
166             pSvc->Release();
167             pLoc->Release();
168             CoUninitialize();
169             return -8;              
170         }
171         while (pEnumerator)
172         {
173             HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
174             if(0 == uReturn)
175             {
176                 break;
177             }
178             VARIANT vtProp;
179             hr = pclsObj->Get(L"DiskIndex", 0, &vtProp, 0, 0); 
180         diskIndex = vtProp.intVal;
181             VariantClear(&vtProp);
182             pclsObj->Release();
183       } 
184 
185     //根据系统所在硬盘的ID查询序列号
186     char index[10];
187     string strQuery = "SELECT * FROM Win32_DiskDrive WHERE Index = ";
188     itoa(diskIndex,index,10);
189     string indexStr(index);
190     strQuery += indexStr;
191     pEnumerator->Release();
192         pEnumerator=NULL;
193         hres = pSvc->ExecQuery(
194             bstr_t("WQL"),
195             bstr_t(strQuery.c_str()),  
196             WBEM_FLAG_FORWARD_ONLY |     WBEM_FLAG_RETURN_IMMEDIATELY,
197             NULL,
198             &pEnumerator);
199         if (FAILED(hres))
200         {
201             pSvc->Release();
202             pLoc->Release();
203             CoUninitialize();
204             return -8;              
205         }
206         while (pEnumerator)
207         {
208             HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
209             if(0 == uReturn)
210             {
211                 break;
212             }
213             VARIANT vtProp;
214             hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0); 
215             wcstombs(info.SystemDiskID,vtProp.bstrVal,20);
216         Trims(info.SystemDiskID);
217             VariantClear(&vtProp);
218             pclsObj->Release();
219         } 
220 
221     //获取BIOS序列号
222     pEnumerator->Release();
223         pEnumerator=NULL;
224         hres = pSvc->ExecQuery(
225             bstr_t("WQL"),
226             bstr_t("SELECT * FROM Win32_BIOS"),
227             WBEM_FLAG_FORWARD_ONLY |     WBEM_FLAG_RETURN_IMMEDIATELY,
228             NULL,
229             &pEnumerator);
230        if (FAILED(hres))
231         {
232             pSvc->Release();
233             pLoc->Release();
234             CoUninitialize();
235             return -9;              
236         }
237         while (pEnumerator)
238         {
239             HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
240             if(0 == uReturn)
241             {
242                 break;
243             }
244             VARIANT vtProp;
245             hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0); 
246         wcstombs(info.BIOSID,vtProp.bstrVal,20);
247             VariantClear(&vtProp);
248             pclsObj->Release();
249         } 
250 
251     
252     //获取本地连接的MAC地址
253     pEnumerator->Release();
254         pEnumerator=NULL;
255         hres = pSvc->ExecQuery(
256             bstr_t("WQL"),
257             bstr_t("SELECT * FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))"),
258             WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
259             NULL,
260             &pEnumerator);
261         if (FAILED(hres))
262         {
263             pSvc->Release();
264             pLoc->Release();
265             CoUninitialize();
266             return -10;              
267         }
268        while (pEnumerator)
269         {
270             HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
271             if(0 == uReturn)
272             {
273             break;
274         }
275         VARIANT vtProp;
276 
277         hr = pclsObj->Get(L"Description", 0, &vtProp, 0, 0); 
278         string des = (_bstr_t)vtProp.bstrVal;
279         if(strstr(des.c_str(),"Ethernet Connection") != NULL)
280         {
281             hr = pclsObj->Get(L"MacAddress", 0, &vtProp, 0, 0);
282             wcstombs(info.MacAddress,vtProp.bstrVal,20);
283         }
284             VariantClear(&vtProp);    
285         pclsObj->Release();
286         } 
287 
288     pSvc->Release();
289     pLoc->Release();
290     pEnumerator->Release();
291     CoUninitialize();
292 
293     return 0;   
294 }
295 
296                                 
View Code

 

在我自己的win7电脑(64位)上测试过,可以获取到想要的硬件信息,但是在公司另一台win7电脑(32位)上,只获取到cpu_id字段,其他几个字段为空。

出现这样的问题,我也不太清楚是由于WMI编程代码的问题,还是电脑主机的问题。如果有码友看出我代码中的问题,欢迎留言指教~

另外查阅了一些资料,有人说可以用DeviceIoControl函数来实现获取主机硬件信息,所以我现在要去研究DeviceIoControl函数啦~

 

posted @ 2017-02-13 11:47  Annie_L  阅读(9047)  评论(2编辑  收藏  举报