设为首页 收藏本站
查看: 2030|回复: 0

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

[复制链接]

尚未签到

发表于 2017-7-7 18:17:26 | 显示全部楼层 |阅读模式
  最近在公司实习,有个应用需要获取windows主机的一些硬件信息,在网上查阅了一些资料,大部分都是使用WMI编程来实现的。
  因此小菜鸟自己也用WMI实现了一下,封装为函数GetUserInfo(),具体代码如下:
  头文件UserInfo.h:


DSC0000.gif DSC0001.gif


#pragma once
#include "stdafx.h"
#define _WIN32_DCOM
#include <comdef.h>
#include <Wbemidl.h>
# pragma comment(lib, "wbemuuid.lib")
using namespace std;

typedef struct UserInfo_t
{
     char CpuID[20];                    //CPU序列号
     char BaseBoardID[256];         //主板ID
     char SystemDiskID[256];        //系统所在硬盘的序列号
     char BIOSID[20];                   //BIOS序列号
     char MacAddress[20];             //MAC地址
}UserInfo;

int GetUserInfo(UserInfo &info);
View Code  源代码GetUerInfo.cpp:





#include "UserInfo.h"
#include <windows.h>
void Trims(char* data)           //去掉字符串中的空格
{
     int i=-1,j=0;
     int ch = ' ';

     while(data[++i] != '\0')
     {
         if(data != ch)
         {
             data[j++] = data;
         }
     }
     data[j] = '\0';
}

int GetUserInfo(UserInfo &info)
{
     HRESULT hres;
     memset(&info,0x00,sizeof(UserInfo));
     
     CoUninitialize();
     hres =  CoInitializeEx(0, COINIT_MULTITHREADED);   //第二个参数设置当前线程的并发模式为多线程
     //hres =  CoInitializeEx(0,COINIT_APARTMENTTHREADED);  //并发模式为单线程(即只能在单线程函数中调用GetUserInfo())
     if (FAILED(hres))
     {
         return -1;                  
     }
     hres =  CoInitializeSecurity(
         NULL,
         -1,                          
         NULL,                        
         NULL,                        
         RPC_C_AUTHN_LEVEL_DEFAULT,   
         RPC_C_IMP_LEVEL_IMPERSONATE,
         NULL,                        
         EOAC_NONE,                  
         NULL                        
         );
     if (FAILED(hres))
     {
         CoUninitialize();
         return -2;                 
     }
     IWbemLocator *pLoc = NULL;
     hres = CoCreateInstance(
         CLSID_WbemLocator,            
         0,
         CLSCTX_INPROC_SERVER,
         IID_IWbemLocator, (LPVOID *) &pLoc);
     if (FAILED(hres))
     {
         CoUninitialize();
         return -3;   
     }
     IWbemServices *pSvc = NULL;
     hres = pLoc->ConnectServer(
         _bstr_t(L"ROOT\\CIMV2"),
         NULL,                    
         NULL,                    
         0,                       
         NULL,                    
         0,                       
         0,                       
         &pSvc                    
         );
     if (FAILED(hres))
     {
         pLoc->Release();     
         CoUninitialize();
         return -4;               
     }
     hres = CoSetProxyBlanket(
         pSvc,                       
         RPC_C_AUTHN_WINNT,           
         RPC_C_AUTHZ_NONE,            
         NULL,                           
         RPC_C_AUTHN_LEVEL_CALL,      
         RPC_C_IMP_LEVEL_IMPERSONATE,
         NULL,                        
         EOAC_NONE                    
         );
     if (FAILED(hres))
     {
         pSvc->Release();
         pLoc->Release();     
         CoUninitialize();
         return -5;              
     }

     //获取CPU序列号
     IEnumWbemClassObject* pEnumerator = NULL;
     hres = pSvc->ExecQuery(
         bstr_t("WQL"),
         bstr_t("SELECT * FROM win32_Processor"),
         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
         NULL,
         &pEnumerator);
     if (FAILED(hres))
     {
         pSvc->Release();
         pLoc->Release();
         CoUninitialize();
         return -6;              
     }
     IWbemClassObject *pclsObj;
     ULONG uReturn = 0;
     while (pEnumerator)
     {
         HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
         if(0 == uReturn)
         {
             break;
         }
         VARIANT vtProp;
         hr = pclsObj->Get(L"ProcessorId", 0, &vtProp, 0, 0);  
         wcstombs(info.CpuID,vtProp.bstrVal,18);
         VariantClear(&vtProp);
         pclsObj->Release();
     }
     
     //获取主板ID
     pEnumerator->Release();
         pEnumerator=NULL;
         hres = pSvc->ExecQuery(
         bstr_t("WQL"),
         bstr_t("SELECT * FROM Win32_BaseBoard"),
         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
         NULL,
         &pEnumerator);
         if (FAILED(hres))
         {
             pSvc->Release();
             pLoc->Release();
             CoUninitialize();
             return -7;              
         }
         while (pEnumerator)
         {
             HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
             if(0 == uReturn)
             {
                 break;
             }
             VARIANT vtProp;
             hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0);
         wcstombs(info.BaseBoardID,vtProp.bstrVal,20);
             VariantClear(&vtProp);
             pclsObj->Release();   
         }
     
     //获取系统所在硬盘的ID
     int diskIndex = 0;
     pEnumerator->Release();
         pEnumerator=NULL;
         hres = pSvc->ExecQuery(
             bstr_t("WQL"),
             bstr_t("SELECT * FROM Win32_DiskPartition WHERE Bootable = TRUE"),  //查找启动盘
             WBEM_FLAG_FORWARD_ONLY |                        WBEM_FLAG_RETURN_IMMEDIATELY,
             NULL,
             &pEnumerator);
         if (FAILED(hres))
         {
             pSvc->Release();
             pLoc->Release();
             CoUninitialize();
             return -8;              
         }
         while (pEnumerator)
         {
             HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
             if(0 == uReturn)
             {
                 break;
             }
             VARIANT vtProp;
             hr = pclsObj->Get(L"DiskIndex", 0, &vtProp, 0, 0);
         diskIndex = vtProp.intVal;
             VariantClear(&vtProp);
             pclsObj->Release();
       }

     //根据系统所在硬盘的ID查询序列号
     char index[10];
     string strQuery = "SELECT * FROM Win32_DiskDrive WHERE Index = ";
     itoa(diskIndex,index,10);
     string indexStr(index);
     strQuery += indexStr;
     pEnumerator->Release();
         pEnumerator=NULL;
         hres = pSvc->ExecQuery(
             bstr_t("WQL"),
             bstr_t(strQuery.c_str()),  
             WBEM_FLAG_FORWARD_ONLY |     WBEM_FLAG_RETURN_IMMEDIATELY,
             NULL,
             &pEnumerator);
         if (FAILED(hres))
         {
             pSvc->Release();
             pLoc->Release();
             CoUninitialize();
             return -8;              
         }
         while (pEnumerator)
         {
             HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
             if(0 == uReturn)
             {
                 break;
             }
             VARIANT vtProp;
             hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0);
             wcstombs(info.SystemDiskID,vtProp.bstrVal,20);
         Trims(info.SystemDiskID);
             VariantClear(&vtProp);
             pclsObj->Release();
         }

     //获取BIOS序列号
     pEnumerator->Release();
         pEnumerator=NULL;
         hres = pSvc->ExecQuery(
             bstr_t("WQL"),
             bstr_t("SELECT * FROM Win32_BIOS"),
             WBEM_FLAG_FORWARD_ONLY |     WBEM_FLAG_RETURN_IMMEDIATELY,
             NULL,
             &pEnumerator);
        if (FAILED(hres))
         {
             pSvc->Release();
             pLoc->Release();
             CoUninitialize();
             return -9;              
         }
         while (pEnumerator)
         {
             HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
             if(0 == uReturn)
             {
                 break;
             }
             VARIANT vtProp;
             hr = pclsObj->Get(L"SerialNumber", 0, &vtProp, 0, 0);
         wcstombs(info.BIOSID,vtProp.bstrVal,20);
             VariantClear(&vtProp);
             pclsObj->Release();
         }

     //获取本地连接的MAC地址
     pEnumerator->Release();
         pEnumerator=NULL;
         hres = pSvc->ExecQuery(
             bstr_t("WQL"),
             bstr_t("SELECT * FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))"),
             WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
             NULL,
             &pEnumerator);
         if (FAILED(hres))
         {
             pSvc->Release();
             pLoc->Release();
             CoUninitialize();
             return -10;              
         }
        while (pEnumerator)
         {
             HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
             if(0 == uReturn)
             {
             break;
         }
         VARIANT vtProp;

         hr = pclsObj->Get(L"Description", 0, &vtProp, 0, 0);
         string des = (_bstr_t)vtProp.bstrVal;
         if(strstr(des.c_str(),"Ethernet Connection") != NULL)
         {
             hr = pclsObj->Get(L"MacAddress", 0, &vtProp, 0, 0);
             wcstombs(info.MacAddress,vtProp.bstrVal,20);
         }
             VariantClear(&vtProp);   
         pclsObj->Release();
         }

     pSvc->Release();
     pLoc->Release();
     pEnumerator->Release();
     CoUninitialize();

     return 0;   
}

                                 
View Code  在我自己的win7电脑(64位)上测试过,可以获取到想要的硬件信息,但是在公司另一台win7电脑(32位)上,只获取到cpu_id字段,其他几个字段为空。
  出现这样的问题,我也不太清楚是由于WMI编程代码的问题,还是电脑主机的问题。如果有码友看出我代码中的问题,欢迎留言指教~
  另外查阅了一些资料,有人说可以用DeviceIoControl函数来实现获取主机硬件信息,所以我现在要去研究DeviceIoControl函数啦~

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-391339-1-1.html 上篇帖子: mac环境下mentohust锐捷登录配置 下篇帖子: IOS:::mac系统如何显示或者隐藏隐形的文件夹
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表