QT/C++获取电脑系统,主板型号,CPU型号,硬盘型号,内存大小等相关信息(二)通过Windows Server (WMI)查询

16 篇文章 22 订阅 ¥99.90 ¥299.90

Qt/C++调用windows Api库通过wmi的方式查询电脑能获取更多详细信息,也更加合理有技术性。
建议使用MSCV编译器,如MSCV 2017 ,Qt版本 : 5.13.1

关于 WMI

关于 WMI
Windows Management Instrumentation (WMI) 是 Microsoft 对基于 Web 的企业管理 (WBEM) 的实现,WBEM 是一项业界倡议,用于为访问企业环境中的管理信息开发一项标准技术。 WMI 使用通用信息模型 (CIM) 行业标准来表示系统、应用程序、网络、设备和其他托管组件

示例:创建 WMI 应用程序

创建 WMI 应用程序
官方代码示例:后续调用基本参照这种格式,值得注意的是需要把COINIT_MULTITHREADED 改为:COINIT_APARTMENTTHREADED
参考详见:
Qt中使用WMI时遇到的那些坑
示例:从本地计算机获取 WMI 数据
CIMWin32 WMI 提供程序-计算机系统硬件类

示例:打印Wmi执行的查询项的所有属性

通过获取第一条数据的属性字段名称,打印输出所有属性:

头文件引用项:

#include <iostream>
#include <comdef.h>
#include <WbemIdl.h>
#include <comutil.h>
#include <Windows.h>
#include <QStorageInfo>
#pragma comment(lib, "wbemuuid.lib")
#pragma comment(lib, "comsuppw.lib")

输出类型转换

QString check_vatiant_type(VARIANT Value,CIMTYPE _enum_type)
{
    switch ( _enum_type ){
    case CIM_ILLEGAL ://值: 0xfff非法值。
        return QString::fromWCharArray(Value.bstrVal);
    case CIM_EMPTY : //值: 0 空 (null) 值。
        return "NULL";
    case CIM_SINT8 : //值: 16//8 位有符号整数。
        return  QString::number(Value.iVal);
    case CIM_SINT16 : //值: 2//16 位带符号整数。
          return  QString::number(Value.iVal);
    case CIM_SINT32 : //值: 3//32 位带符号整数。
        return  QString::number(Value.intVal);
    case CIM_SINT64 : //值: 20//64 位带符号整数。
         return  QString::number(Value.llVal,10);
    case CIM_UINT8 : //值: 17//8 位无符号整数。
          return  QString::number(Value.uiVal);
    case CIM_UINT16 : //值: 18//16 位无符号整数。
         return  QString::number(Value.uintVal);
    case CIM_UINT32 : //值: 19//32 位无符号整数。
             return  QString::number(Value.uintVal);
    case CIM_UINT64 : //值: 21//64 位无符号整数。
     return  QString::number(Value.ullVal,10);
    case CIM_REAL32 : //值: 4//32 位实数。
         return  QString::number(Value.intVal);
    case CIM_REAL64 : //值: 5//64 位实数。
        return  QString::number(Value.ullVal,10);
    case CIM_BOOLEAN : //值: 11//一个布尔值。
        return Value.boolVal?"TRUE":"FALSE";
    case CIM_STRING : // 值: 8// 字符串值。
        return QString::fromWCharArray(Value.bstrVal);
    case CIM_DATETIME : //值: 101//一个日期时间值。
    case CIM_REFERENCE : //值: 102//另一个对象的引用 (__Path) 。
    case CIM_CHAR16 : //值: 103//16 位字符值。
    case CIM_OBJECT : //值: 13//Object 值 。
    case CIM_FLAG_ARRAY : // 值: 0x2000//数组值。
         return QString::fromWCharArray(Value.bstrVal);
    default:
        return QString::fromWCharArray(Value.bstrVal);
    }
}

执行查询

///输入 table_name /表名称 如: Win32_Refrigeration
void SelectWmi(QString table_name)
{
    HRESULT hres;
    // Step 1: --------------------------------------------------
    // Initialize COM. ------------------------------------------
    hres =  CoInitializeEx(0, COINIT_APARTMENTTHREADED);
    if (FAILED(hres))
    {
        //Qt中使用WMI时遇到的那些坑儿
        //https://blog.csdn.net/wangshubo1989/article/details/51869644
        qDebug() << "Failed to initialize COM library. Error code = 0x"
                 << hex << hres << endl;
        return ;                  // Program has failed.
    }

    // Step 2: --------------------------------------------------
    // Set general COM security levels --------------------------

    hres =  CoInitializeSecurity(
                NULL,
                -1,                          // COM authentication
                NULL,                        // Authentication services
                NULL,                        // Reserved
                RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication
                RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
                NULL,                        // Authentication info
                EOAC_NONE,                   // Additional capabilities
                NULL                         // Reserved
                );


    if ((hres != RPC_E_TOO_LATE) && FAILED(hres))
    {
        qDebug() << "Failed to initialize security. Error code = 0x"
                 << hex << hres << endl;
        CoUninitialize();
        return ;                    // Program has failed.
    }

    // Step 3: ---------------------------------------------------
    // Obtain the initial locator to WMI -------------------------

    IWbemLocator *pLoc = NULL;

    hres = CoCreateInstance(
                CLSID_WbemLocator,
                0,
                CLSCTX_INPROC_SERVER,
                IID_IWbemLocator, (LPVOID *) &pLoc);

    if (FAILED(hres))
    {
        qDebug() << "Failed to create IWbemLocator object."
                 << " Err code = 0x"
                 << hex << hres << endl;
        CoUninitialize();
        return ;                 // Program has failed.
    }

    // Step 4: -----------------------------------------------------
    // Connect to WMI through the IWbemLocator::ConnectServer method

    IWbemServices *pSvc = NULL;

    // Connect to the root\cimv2 namespace with
    // the current user and obtain pointer pSvc
    // to make IWbemServices calls.
    hres = pLoc->ConnectServer(
                _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
                NULL,                    // User name. NULL = current user
                NULL,                    // User password. NULL = current
                0,                       // Locale. NULL indicates current
                NULL,                    // Security flags.
                0,                       // Authority (for example, Kerberos)
                0,                       // Context object
                &pSvc                    // pointer to IWbemServices proxy
                );

    if (FAILED(hres))
    {
        qDebug() << "Could not connect. Error code = 0x"
                 << hex << hres << endl;
        pLoc->Release();
        CoUninitialize();
        return ;                // Program has failed.
    }

    qDebug() << "Connected to ROOT\\CIMV2 WMI namespace" << endl;


    // Step 5: --------------------------------------------------
    // Set security levels on the proxy -------------------------

    hres = CoSetProxyBlanket(
                pSvc,                        // Indicates the proxy to set
                RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
                RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
                NULL,                        // Server principal name
                RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx
                RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
                NULL,                        // client identity
                EOAC_NONE                    // proxy capabilities
                );

    if (FAILED(hres))
    {
        qDebug() << "Could not set proxy blanket. Error code = 0x"
                 << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return ;               // Program has failed.
    }

    // Step 6: --------------------------------------------------
    // Use the IWbemServices pointer to make requests of WMI ----

    // For example, get the name of the operating system
    IEnumWbemClassObject* pEnumerator = NULL;
    hres = pSvc->ExecQuery(
                bstr_t("WQL"),
                bstr_t(QString("SELECT * FROM "+table_name.trimmed()).toStdWString().c_str()),
                WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
                NULL,
                &pEnumerator);

    if (FAILED(hres))
    {
        qDebug() << "Query for operating system name failed."
                 << " Error code = 0x"
                 << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return ;               // Program has failed.
    }

    // Step 7: -------------------------------------------------
    // Get the data from the query in step 6 -------------------
    //IWbemClassObject 接口包含和操作类定义和类对象实例。
    ///属性字段列表
    QList<BSTR> Headerlist;
    ///属性值 全部转换成字符串 用于显示到界面
    QList<QStringList> Datas;
    IWbemClassObject *pclsObj = NULL;
    while (pEnumerator)
    {
        ULONG uReturn = 0;
        HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);

        if(0 == uReturn || pclsObj == NULL)
        {
            break;
        }
        if(Headerlist.count()==0)
        {
            SAFEARRAY* pNames;
            hres=pclsObj->GetNames(L"",WBEM_FLAG_ALWAYS,NULL,&pNames);
            if (FAILED(hres))
            {
                qDebug()<<"获取属性名称失败!";
            }

            qDebug()<<"lLbound : "<<pNames->cDims;
            qDebug()<<"cbElements : "<<pNames->cbElements;
            BSTR HUGEP *pbstr;
            // Get a pointer to the elements of the array.
            hr = SafeArrayAccessData(pNames, (void HUGEP**)&pbstr);
            if (FAILED(hr))
                continue;
            for (int i = 0; i < pNames->rgsabound->cElements; i++)
            {
                 BSTR bstrTemp = pbstr[i];
                Headerlist.append(bstrTemp);
            }
            SafeArrayDestroy(pNames);
        }
        if(Headerlist.count()==0)
            continue;

        QStringList _Data;
        foreach (BSTR name , Headerlist) {
             VARIANT vtProp;
             CIMTYPE  pType= CIM_EMPTY;
             VariantInit(&vtProp);
             hr = pclsObj->Get(name, 0, &vtProp, &pType, 0);
             if(FAILED(hr))
             {
                 _Data.append("ERROR");
             }
             else
                 _Data.append(check_vatiant_type(vtProp,pType));
             VariantClear(&vtProp);
        }
        Datas.append(_Data);
        pclsObj->Release();
    }
    emit SendTabValues(Headerlist,Datas);

    // Cleanup
    // ========
    pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
    CoUninitialize();
}

通过Windows PowerShell 查询WMI 属性

在WMI 众多查询项中,如果需要预先简要查看相关属性,可以通过Windows PowerShell输入查询;
windows+ X 选择Windows PowerShell (管理员)查询:
以查询磁盘为例:
输入:Get-WmiObject -query "SELECT * FROM Win32_DiskDrive"
在这里插入图片描述
指定项查询:Get-WmiObject -query "SELECT name,Partitions,DeviceID,Model,Size,Caption,SystemName FROM WIN32_DiskDrive"
在这里插入图片描述

示例:通过WMI 查询电脑属性

查询磁盘 盘符信息:

代码:select DeviceID,DriveType,FreeSpace,Size,VolumeName,FileSystem from Win32_LogicalDisk
在这里插入图片描述

获取当前系统版本

代码:SELECT Caption,Name,OSArchitecture FROM Win32_OperatingSystem
在这里插入图片描述

获取主板型号

代码:SELECT Product From Win32_BaseBoard
在这里插入图片描述

获取CPU型号

代码:SELECT Name FROM Win32_Processor

获取显卡型号

代码:select Name from Win32_VideoController

获取内存大小

代码:SELECT TotalPhysicalMemory FROM Win32_ComputerSystem

获取电脑类型

代码:SELECT ChassisTypes FROM Win32_SystemEnclosure

获取硬盘型号

代码:SELECT Model From Win32_DiskDrive

示例源码

链接: https://pan.baidu.com/s/1QEGau1LQalW7HXv0E3kejA
提取码: 666v
双击查询电脑常用详细属性
编译器:MSCV2017 | QtCreator 5.13.1
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

得鹿梦鱼、

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值