使用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);

源代码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

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

c# WMI获取机器硬件信息(硬盘,cpu,内存等)

using System; using System.Collections.Generic; using System.Globalization; using System.Management; using System.IO; using System.Net; using System.Net.NetworkInformation; using System.Net.Sockets; using System.Runtime.InteropServices; using System.

Linux用户和组管理,查看软件缓存,通过命令查看硬件信息(cpu,版本,序列号,内存,主板,内核等)

 通过修改/etc/inittab.通过这个文件修改系统的启动方式. ls –l /etc/ | more   (管道),将前面的结果交给后面的命令进行处理. 在linux中遇到问题使用man命令. 查找文件信息并将文件存储到一个制定的文件中. ls –la > "a.txt" 创建组名: 创建组: 查看Linux中所有组的信息:cat /etc/group | more 其中root:x:0 root:表示组名,x:表示加密后的权限声明,0:表示root组的id号. 7创建

C#获取当前主机硬件信息

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks; using System.Net;using System.Management;  //在项目->添加引用....里面引用System.Managementusing System.Runtime.InteropServices; namespace FileSplit{

用C#获取电脑硬件信息

现在我将来解释如何在C#中用WMI(Windows Management Instrumentation)来获取电脑的硬件信息. 我们的目的是用WMI的api在C#下获取电脑的以下信息: 物理处理器的数量 逻辑处理器的数量 位数 系统构架 内核数量 在Visual Studio中创建一个控制台应用程序,并且右击引用然后选择"添加引用",再选择"System.Management". 现在已经通过using语句包括了System.Management,你可以在你的代码

通过js获取计算机内网ip,计算机名,mac地址

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> <head> <meta http-equiv="

使用gethostname()函数和gethostbyname()函数获取主机相关信息

from http://ty1992.blog.51cto.com/7098269/1685880 gethostname() : 返回本地主机的标准主机名. 原型如下: #include <unistd.h> int gethostname(char *name, size_t len); 参数说明: 这个函数需要两个参数: 接收缓冲区name,其长度必须为len字节或是更长,存获得的主机名. 接收缓冲区name的最大长度 返回值: 如果函数成功,则返回0.如果发生错误则返回-1.错误号存放

检测硬件的批处理命令,检测硬件bat,一键获取电脑硬件信息

警告:运行BAT源码是一种危险的动作,如果你不熟悉,请不要尝试! 批处理语言: 简体中文 授权方式: 免费软件 运行环境: Windows平台 检测硬件批处理命令.一键获取.直接双击就可以查看 @echo off color 0a title 硬件检测 mode con cols=90 sc config winmgmt start= auto >nul 2<&1 net start winmgmt 2>1nul setlocal ENABLEDELAYEDEXPANSION e

使用gethostnam()函数和gethostbyname()函数获取主机相关信息

gethostname() : 返回本地主机的标准主机名. 原型如下: #include <unistd.h> int gethostname(char *name, size_t len); 参数说明: 这个函数需要两个参数: 接收缓冲区name,其长度必须为len字节或是更长,存获得的主机名. 接收缓冲区name的最大长度 返回值: 如果函数成功,则返回0.如果发生错误则返回-1.错误号存放在外部变量errno中. gethostbyname()函数说明--用域名或主机名获取IP地址  

获取主机相关信息脚本

考核内容 awk 编辑文件抓取ip信息抓取登录用户执行脚本 原文地址:https://blog.51cto.com/14190777/2434108