C++通过WMI获取硬件配置信息

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liubing8609/article/details/82056249

C++通过WMI获取硬件配置信息

WMIWindows管理规范。通过它可以访问、配置、管理和监视几乎所有的Windows资源。

WMI提供程序在WMI和托管资源之间扮演着中间方的角色。提供程序代表使用者应用程序和脚本从WMI托管资源请求信息,并发送指令到WMI托管资源。

下面是我们利用WMI编程经常要用到的WMI内置提供程序清单,以供编程参考。

1. Active Directory提供程序

链接库文件:dsprov.dll

命名空间:root\directory\ldap

作用:将Active Directory 对象映射到 WMI

2. 事件日志提供程序

链接库文件:ntevt.dll

命名空间:root\cimv2

作用:管理 Windows 事件日志,例如,读取、备份、清除、复制、删除、监视、重命名、压缩、解压缩和更改事件日志设置。

3. 注册表提供程序

链接库文件:stdprov.dll

命名空间:root\default

作用:读取、写入、枚举、监视、创建、删除注册表项和值。

4. Win32提供程序

链接库文件:cimwin32.dll

命名空间:root\cimv2

作用:提供关于计算机、磁盘、外围设备、文件、文件夹、文件系统、网络组件、操作系统、打印机、进程、安全性、服务、共享、SAM 用户及组,以及更多资源的信息。

5. Windows安装程序提供程序

链接库文件:msiprov.dll

命名空间:root\cimv2

作用:提供对已安装软件信息的访问。

以上可以看出WMI中的类被分组到不同的命名空间中,所以我们在调用相应的程序库时要注意引入对应的命名空间。我们今天用到的库就是cimwin32.dll库(第4个)。

通过WMIwindows管理规范)接口编程来实现系统硬件信息的获取方便多了,使用起来是相当的方便,但是速度有点慢。

// 头文件

#pragma once

#include <atlbase.h>

#include <afxpriv.h>

#include <WbemIdl.h>

#pragma comment(lib,"WbemUuid.lib")

 

class CWmiInfo

{

public:

        CWmiInfo(void);

        ~CWmiInfo(void);

 

public:

        HRESULT InitWmi();    //初始化WMI

        HRESULT ReleaseWmi(); //释放

 

               

        BOOL GetSingleItemInfo(CString,CString,CString&);

        BOOL GetGroupItemInfo(CString,CString[],int,CString&);

 

private:

        void VariantToString(const LPVARIANT,CString &) const;//Variant类型的变量转换为CString

private:

        IEnumWbemClassObject* m_pEnumClsObj;

        IWbemClassObject* m_pWbemClsObj;

        IWbemServices* m_pWbemSvc;

        IWbemLocator* m_pWbemLoc;

};

#include "StdAfx.h"

#include "WmiInfo.h"

 

CWmiInfo::CWmiInfo(void)

{

        m_pWbemSvc=NULL;

        m_pWbemLoc=NULL;

        m_pEnumClsObj = NULL;

}

 

// 源文件

CWmiInfo::~CWmiInfo(void)

{

        m_pWbemSvc=NULL;

        m_pWbemLoc=NULL;

        m_pEnumClsObj = NULL;

}

 

HRESULT CWmiInfo::InitWmi()

{

        HRESULT hr;

 

// 初始化COM组件

        //初始化COM

        hr=::CoInitializeEx(0,COINIT_MULTITHREADED);

        if (SUCCEEDED(hr) || RPC_E_CHANGED_MODE == hr)

        {

                //设置进程的安全级别,(调用COM组件时在初始化COM之后要调用CoInitializeSecurity设置进程安全级别,否则会被系统识别为病毒)

                hr=CoInitializeSecurity(NULL,

                        -1,

                        NULL,                  

                        NULL,

                        RPC_C_AUTHN_LEVEL_PKT,

                        RPC_C_IMP_LEVEL_IMPERSONATE,

                        NULL,

                        EOAC_NONE,

                        NULL);

                //VERIFY(SUCCEEDED(hr));

 

                // 创建一个WMI命名空间连接

                //创建一个CLSID_WbemLocator对象

                hr=CoCreateInstance(CLSID_WbemLocator,

                        0,

                        CLSCTX_INPROC_SERVER,

                        IID_IWbemLocator,

                        (LPVOID*)&m_pWbemLoc);

                VERIFY(SUCCEEDED(hr));

 

                //使用m_pWbemLoc连接到"root\cimv2"并设置m_pWbemSvc的指针

                hr=m_pWbemLoc->ConnectServer(CComBSTR(L"ROOT\\CIMV2"),

                        NULL,

                        NULL,

                        0,

                        NULL,

                        0,

                        0,

                        &m_pWbemSvc);

                VERIFY(SUCCEEDED(hr));

 

                // 设置WMI连接的安全性

                hr=CoSetProxyBlanket(m_pWbemSvc,

                        RPC_C_AUTHN_WINNT,

                        RPC_C_AUTHZ_NONE,

                        NULL,

                        RPC_C_AUTHN_LEVEL_CALL,

                        RPC_C_IMP_LEVEL_IMPERSONATE,

                        NULL,

                        EOAC_NONE);

                VERIFY(SUCCEEDED(hr));

 

        }

        return(hr);

}

 

HRESULT CWmiInfo::ReleaseWmi()

{

        HRESULT hr;

 

        if (NULL != m_pWbemSvc)

        {

                hr=m_pWbemSvc->Release();

        }

        if (NULL != m_pWbemLoc)

        {

                hr=m_pWbemLoc->Release();

        }

        if (NULL != m_pEnumClsObj)

        {

                hr=m_pEnumClsObj->Release();

        }

 

        ::CoUninitialize();

 

        return(hr);

}

 

BOOL CWmiInfo::GetSingleItemInfo(CString ClassName,CString ClassMember,CString &chRetValue)

{

        USES_CONVERSION;

 

        CComBSTR query("SELECT * FROM ");

        VARIANT vtProp;

        ULONG uReturn;

        HRESULT hr;

        BOOL bRet = FALSE;

 

        if (NULL != m_pWbemSvc)

        {

                //查询类ClassName中的所有字段,保存到m_pEnumClsObj

                query+=CComBSTR(ClassName);

                hr=m_pWbemSvc->ExecQuery(CComBSTR("WQL"),query,WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,

                        0,&m_pEnumClsObj);

                if (SUCCEEDED(hr))

                {

                        //初始化vtProp

                        VariantInit(&vtProp);

                        uReturn=0;

 

                        //返回从当前位置起的第一个对象到m_pWbemClsObj

                        hr=m_pEnumClsObj->Next(WBEM_INFINITE,1,&m_pWbemClsObj,&uReturn);

                        if(SUCCEEDED(hr)&&uReturn>0)

                        {

                                //m_pWbemClsObj中找出ClassMember标识的成员属性值,并保存到vtProp变量中

                                hr=m_pWbemClsObj->Get(CComBSTR(ClassMember),0,&vtProp,0,0);

                                if (SUCCEEDED(hr))

                                {

                                        VariantToString(&vtProp,chRetValue);

                                        VariantClear(&vtProp);//清空vtProp

                                        bRet = TRUE;

                                }

                        }

                }

        }

        if(NULL != m_pEnumClsObj)

        {

                hr=m_pEnumClsObj->Release();

                m_pEnumClsObj = NULL;

        }

        if(NULL != m_pWbemClsObj)

        {

                hr=m_pWbemClsObj->Release();

                m_pWbemClsObj = NULL;

        }

        return bRet;

}

 

BOOL CWmiInfo::GetGroupItemInfo(CString ClassName,CString ClassMember[],int n,CString &chRetValue)

{

        USES_CONVERSION;

 

        CComBSTR query("SELECT * FROM ");

        CString result,info;

        VARIANT vtProp;

        ULONG uReturn;

        HRESULT hr;

        int i;

        BOOL bRet = FALSE;

        if (NULL  != m_pWbemSvc)

        {

                query+=CComBSTR(ClassName);

                hr=m_pWbemSvc->ExecQuery(CComBSTR("WQL"),query,WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY,0,&m_pEnumClsObj);

                if (SUCCEEDED(hr))

                {

                        VariantInit(&vtProp); //初始化vtProp变量

                        if(m_pEnumClsObj)  

                        {

                                Sleep(10);

                                uReturn=0;

                                hr=m_pEnumClsObj->Next(WBEM_INFINITE,1,&m_pWbemClsObj,&uReturn);

                                if (SUCCEEDED(hr) &&uReturn>0)

                                {

                                        for(i=0;i<n;++i)

                                        {

                                                hr=m_pWbemClsObj->Get(CComBSTR(ClassMember[i]),0,&vtProp,0,0);

                                                if (SUCCEEDED(hr))

                                                {

                                                        VariantToString(&vtProp,info);

                                                        chRetValue+=info+_T("\t");

                                                        VariantClear(&vtProp);

                                                        bRet = TRUE;

                                                }

                                        }

                                        chRetValue+=_T("\r\n");

                                }

                        }

                }

        }

 

        if(NULL != m_pEnumClsObj)

        {

                hr=m_pEnumClsObj->Release();

                m_pEnumClsObj=NULL;

        }

        if(NULL != m_pWbemClsObj)

        {

                hr=m_pWbemClsObj->Release();

                m_pWbemClsObj=NULL;

        }

        return bRet;

}

 

void CWmiInfo::VariantToString(const LPVARIANT pVar,CString &chRetValue) const

{

        USES_CONVERSION;

 

        CComBSTR HUGEP* pBstr;

        BYTE HUGEP* pBuf;

        LONG low,high,i;

        HRESULT hr;

 

        switch(pVar->vt)

        {

        case VT_BSTR:

                {

                        chRetValue=W2T(pVar->bstrVal);

                }

                break;

        case VT_BOOL:

                {

                        if(VARIANT_TRUE==pVar->boolVal)

                                chRetValue="";

                        else

                                chRetValue="";

                }

                break;

        case VT_I4:

                {

                        chRetValue.Format(_T("%d"),pVar->lVal);

                }

                break;

        case VT_UI1:

                {

                        chRetValue.Format(_T("%d"),pVar->bVal);

                }

                break;

        case VT_UI4:

                {

                        chRetValue.Format(_T("%d"),pVar->ulVal);

                }

                break;

 

        case VT_BSTR|VT_ARRAY:

                {

                        hr=SafeArrayAccessData(pVar->parray,(void HUGEP**)&pBstr);

                        hr=SafeArrayUnaccessData(pVar->parray);

                        chRetValue=W2T(pBstr->m_str);

                }

                break;

 

        case VT_I4|VT_ARRAY:

                {

                        SafeArrayGetLBound(pVar->parray,1,&low);

                        SafeArrayGetUBound(pVar->parray,1,&high);

 

                        hr=SafeArrayAccessData(pVar->parray,(void HUGEP**)&pBuf);

                        hr=SafeArrayUnaccessData(pVar->parray);

                        CString strTmp;

                        high=min(high,MAX_PATH*2-1);

                        for(i=low;i<=high;++i)

                        {

                                strTmp.Format(_T("%02X"),pBuf[i]);

                                chRetValue+=strTmp;

                        }

                }

                break;

        default:

                break;

        }

}

上面就是一个WMI的封装,返回参数均以CString类型返回调用顺序:

  1. 实例化一个CWmiInfo类对象;
  2. 调用InitWmi()函数初始化COM组件等。函数中有说明必须调用InitWmi初始化WMI组件,否则所有调用都无意义。
  3. 调用GetXXX方法获取你要获取的字段值。
  4. 最后使用完CWmiInfo类对象之后一定要记得调用ReleaseWmi()函数来释放资源。

调用说明:

GetSingleItemInfo()

  1. 第一个参数为要查询的类名如"Win32_Processor"表示CPU类;
  2. 第二个参数表示要查的类的成员,"Caption"表示查询CPU的名称
  3. 第三个参数表示返回值。

故可以这样调用

CString strRetValue;

GetSingleItemInfo(_T("Win32_Processor"),_T("Caption"),strRetValue);

一样调用成功后即可从strRetValue参数中读取出CPU的名称。

GetGroupItemInfo 函数与GetSingleItemInfo类似,不同的是GetSingleItemInfo一次只能查一个类成员而GetGroupItemInfo一次可以查询一个类的多个成员。GetGroupItemInfo的第三个参数表示要查询的类成员的个数,即第二个参数CString数组的大小可以这样调用:

CString strRetValue;CString [] strClassMem = {_T("Caption"),_T("CurrentClockSpeed"),_T("DeviceID"), _T("Manufacturer"),_T("Manufacturer")};GetGroupItemInfo(_T("Win32_Processor"),strClassMem,5,strRetValue);

下面给大家列出一些常用的类名:

// 硬件信息类名

Win32_Processor, // CPU 处理器

Win32_PhysicalMemory, // 物理内存条

Win32_Keyboard, // 键盘

Win32_PointingDevice, // 点输入设备,包括鼠标。

Win32_FloppyDrive, // 软盘驱动器

Win32_DiskDrive, // 硬盘驱动器

Win32_CDROMDrive, // 光盘驱动器

Win32_BaseBoard, // 主板

Win32_BIOS, // BIOS 芯片

Win32_ParallelPort, // 并口

Win32_SerialPort, // 串口

Win32_SerialPortConfiguration, // 串口配置

Win32_SoundDevice, // 多媒体设置,一般指声卡。

Win32_SystemSlot, // 主板插槽 (ISA & PCI & AGP)

Win32_USBController, // USB 控制器

Win32_NetworkAdapter, // 网络适配器

Win32_NetworkAdapterConfiguration, // 网络适配器设置

Win32_Printer, // 打印机

Win32_PrinterConfiguration, // 打印机设置

Win32_PrintJob, // 打印机任务

Win32_TCPIPPrinterPort, // 打印机端口

Win32_POTSModem, // MODEM

Win32_POTSModemToSerialPort, // MODEM 端口

Win32_DesktopMonitor, // 显示器

Win32_DisplayConfiguration, // 显卡

Win32_DisplayControllerConfiguration, // 显卡设置

Win32_VideoController, // 显卡细节。

Win32_VideoSettings, // 显卡支持的显示模式。

// 操作系统

Win32_TimeZone, // 时区

Win32_SystemDriver, // 驱动程序

Win32_DiskPartition, // 磁盘分区

Win32_LogicalDisk, // 逻辑磁盘

Win32_LogicalDiskToPartition, // 逻辑磁盘所在分区及始末位置。

Win32_LogicalMemoryConfiguration, // 逻辑内存配置

Win32_PageFile, // 系统页文件信息

Win32_PageFileSetting, // 页文件设置

Win32_BootConfiguration, // 系统启动配置

Win32_ComputerSystem, // 计算机信息简要

Win32_OperatingSystem, // 操作系统信息

Win32_StartupCommand, // 系统自动启动程序

Win32_Service, // 系统安装的服务

Win32_Group, // 系统管理组

Win32_GroupUser, // 系统组帐号

Win32_UserAccount, // 用户帐号

Win32_Process, // 系统进程

Win32_Thread, // 系统线程

Win32_Share, // 共享

Win32_NetworkClient, // 已安装的网络客户端

Win32_NetworkProtocol, // 已安装的网络协议

猜你喜欢

转载自blog.csdn.net/liubing8609/article/details/82056249