最近在公司实习,有个应用需要获取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);
源代码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
在我自己的win7电脑(64位)上测试过,可以获取到想要的硬件信息,但是在公司另一台win7电脑(32位)上,只获取到cpu_id字段,其他几个字段为空。
出现这样的问题,我也不太清楚是由于WMI编程代码的问题,还是电脑主机的问题。如果有码友看出我代码中的问题,欢迎留言指教~
另外查阅了一些资料,有人说可以用DeviceIoControl函数来实现获取主机硬件信息,所以我现在要去研究DeviceIoControl函数啦~
时间: 2024-10-11 23:30:55