使用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函數啦~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM