当前位置:C++技术网 > 精选软件 > C++获取硬盘序列号、主板序列号、CPU序列号、BIOS序列号和MAC地址

C++获取硬盘序列号、主板序列号、CPU序列号、BIOS序列号和MAC地址

更新时间:2016-10-14 22:57:26浏览次数:1+次

    在很多时候,我们需要获取计算机的硬件信息,以确定一个唯一的计算机。我们可以获取硬盘序列号、主板序列号、CPU序列号、BIOS序列号和MAC地址。通过这些信息,我们基本可以唯一确定一个计算机。

    下面是程序运行的效果图:

C++获取硬盘序列号、主板序列号、CPU序列号、BIOS序列号和MAC地址

    看到了我的电脑是联想Y50c的主板。其他信息都获取到了。

    而这些信息都是通过WMI查询得到的。WMI非常强大,可以查询电脑中各种信息。我们要大批量查询电脑的信息,推荐使用WMI,查询的方式是WQL,和SQL的语句差不多。不过想真正让这个程序跑起来,还是挺费劲的。

    上图中只是查询的很小一部分,实际上还有很多很多可以查询,几乎是电脑中能有的信息都可以查到。不过查询的速度因为使用了WMI,所以相对会慢一点。不过没有太大关系。

    为了支持更好的扩展,我将查询的WQL语句和被查询的字段以数组形式组织,后面可以方便的增加更多的查询选项,然后代码改动就是在数组中添加一组查询,就这么简单。

    下面是我写好的查询代码:


#include <iostream>
using namespace std;
#include <comdef.h>
#include <Wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
bool GetHardwareInfo(char* name,string &value);
string wstring2string(wstring wstr);
wstring string2wstring(string str);
string trim(string str);
void main(int argc, char **argv)
{
    string hd,hdn,board_sn,board_type,cpu,bios,mac;
    GetHardwareInfo("hd",hd);
    GetHardwareInfo("hdn",hdn);
    GetHardwareInfo("board_sn",board_sn);
    GetHardwareInfo("board_type",board_type);
    GetHardwareInfo("cpu",cpu);
    GetHardwareInfo("bios",bios);
    GetHardwareInfo("mac",mac);
    cout<<"硬盘序列  号: "<<hd.c_str()<<endl;
    cout<<"硬盘序列名称: "<<hdn.c_str()<<endl;
    cout<<"主板序列  号: "<<board_sn.c_str()<<endl;
    cout<<"主板  型  号: "<<board_type.c_str()<<endl;
    cout<<"CPU 序列  号: "<<cpu.c_str()<<endl;
    cout<<"BIOS序列  号: "<<bios.c_str()<<endl;
    cout<<"MAC   地  址: "<<mac.c_str()<<endl;
    int i;
    cin>>i;
}
typedef struct
{
    string name;
    string sql;
    string field;
    
}INFO;
bool GetHardwareInfo(char* name,string &value)
{
    INFO query_arr[]=
    {
        {"hd","SELECT * FROM Win32_DiskDrive WHERE (SerialNumber IS NOT NULL) AND (MediaType LIKE 'Fixed hard disk%')","SerialNumber"},// 硬盘序列号
        {"hdn","SELECT * FROM Win32_PhysicalMedia WHERE (SerialNumber IS NOT NULL)","SerialNumber"},// 硬盘序列号 
        {"board_sn","SELECT * FROM Win32_BaseBoard WHERE (SerialNumber IS NOT NULL)","SerialNumber"},// 主板序列号 
        {"board_type","SELECT * FROM Win32_BaseBoard WHERE (Product IS NOT NULL)","Product"},// 主板型号
        {"cpu","SELECT * FROM Win32_Processor WHERE (ProcessorId IS NOT NULL)","ProcessorId"},// 处理器ID  
        {"bios","SELECT * FROM Win32_BIOS WHERE (SerialNumber IS NOT NULL)","SerialNumber"},// BIOS序列号
        {"mac","SELECT * FROM Win32_NetworkAdapter WHERE (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))","MACAddress"}// 网卡当前MAC地址 
    };
    string sql,field;
    for(int i=0;i<7;i++)
    {
        if(0==query_arr[i].name.compare(name))
        {
            sql=query_arr[i].sql;
            field=query_arr[i].field;
        }
    }
    if (sql.empty()||field.empty())return false;

    HRESULT hres;
    //初始化COM环境
    hres =  CoInitializeEx(0, COINIT_MULTITHREADED); 
    if (FAILED(hres))return false;//初始化COM环境失败
    //设置COM安全等级
    hres =  CoInitializeSecurity(
        NULL, 
        -1,                          // COM 认证
        NULL,                        // 认证服务
        NULL,                        // 保留
        RPC_C_AUTHN_LEVEL_DEFAULT,   // 默认认证
        RPC_C_IMP_LEVEL_IMPERSONATE, // 默认模拟  
        NULL,                        // 认证信息
        EOAC_NONE,                   // 附加能力标志 
        NULL                         // 保留
        );

    if (FAILED(hres))
    {
        CoUninitialize();
        return false;//设置COM安全等级失败
    }
    //获取WMI初始定位器IWbemLocator
    IWbemLocator *pLoc = NULL;
    hres = CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER,IID_IWbemLocator, (LPVOID *) &pLoc);
    if (FAILED(hres))
    {
        CoUninitialize();
        return false;//获取WMI初始定位器IWbemLocator失败
    }
    //通过IWbemLocator::ConnectServer连接WMI
    IWbemServices *pSvc = NULL;
    //使用当前用户连接到命名空间root\cimv2
    hres = pLoc->ConnectServer(
        _bstr_t(L"ROOT\\CIMV2"), // WMI命名空间的对象路径
        NULL,                    // 用户名,NULL表示当前用户
        NULL,                    // 用户密码,NULL表示当前用户密码
        0,                       // 位置, NULL 指示当前。
        NULL,                    // 安全标志
        0,                       // 机构
        0,                       // 上下文环境对象
        &pSvc                    // 指向IWbemServices代理的指针
        );

    if (FAILED(hres))
    {
        pLoc->Release();     
        CoUninitialize();
        return false;//无法连接到WMI
    }
    //设置代理的安全等级
    hres = CoSetProxyBlanket(
        pSvc,                        // 被设置的代理
        RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
        RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
        NULL,                        // 服务器主要名字
        RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
        RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
        NULL,                        // 客户端标志
        EOAC_NONE                    // 代理能力标志
        );

    if (FAILED(hres))
    {
        pSvc->Release();
        pLoc->Release();     
        CoUninitialize();
        return false;//设置代理的安全等级失败
    }
    //使用IWbemServices向WMI查询
    IEnumWbemClassObject* pEnumerator = NULL;
    hres = pSvc->ExecQuery((bstr_t)"WQL",(bstr_t)sql.c_str(),WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,NULL,&pEnumerator);
    if (FAILED(hres))
    {
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return false;//查询失败
    }
    //获取查询的数据
    IWbemClassObject *pclsObj=NULL;
    ULONG uReturn = 0;

    while (pEnumerator)
    {
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE,1,&pclsObj, &uReturn);
        if(0 == uReturn)break;
        VARIANT vtProp;
        wstring wstr = string2wstring(field);
        if (!pclsObj)break;
        hr = pclsObj->Get(wstr.c_str(), 0, &vtProp, 0, 0);
        value = _bstr_t(vtProp.bstrVal);
        value = trim(value);
        VariantClear(&vtProp);
    }
    //清除COM环境
    if (pSvc)pSvc->Release();
    if (pLoc)pLoc->Release();
    if (pEnumerator)pEnumerator->Release();
    if (pclsObj)pclsObj->Release();
    CoUninitialize();

    return true;
}
string wstring2string(wstring wstr)
{
    string result;
    int len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), NULL, 0, NULL, NULL);
    if( len <= 0 )return result;
    char* buffer = new char[len + 1];
    if(buffer == NULL )return result;
    WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), buffer, len, NULL, NULL);
    buffer[len] = '\0';
    result.append(buffer);
    delete[] buffer;
    return result;
}
wstring string2wstring(string str)
{
    wstring result;
    int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), NULL, 0);
    if( len < 0 )return result;
    wchar_t* buffer = new wchar_t[len + 1];
    if( buffer == NULL )return result;
    MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), buffer, len);
    buffer[len] = '\0';
    result.append(buffer);
    delete[] buffer;
    return result;
}
string trim(string str)
{
    int s = str.find_first_not_of(" ");
    int e = str.find_last_not_of(" ");
    if (s==-1 && e==-1)return str;
    if (s==-1)
    {
        //结尾空格
        str = str.substr(0,e+1);
    }
    if (e==-1)
    {
        //开头空格
        str = str.substr(s,str.length());
    }
    if (s!=-1 && e!=-1)
    {
        str = str.substr(s,e-s+1);
    }
    return str;
}