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


    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 
    #include 
    #include 
    #include 
    #include 
    #include 
    #pragma comment(lib, "wbemuuid.lib")
    #pragma comment(lib, "comsuppw.lib")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    输出类型转换

    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    执行查询

    ///输入 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();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208

    通过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
    在这里插入图片描述

  • 相关阅读:
    推荐一个react上拉加载更多插件:react-infinite-scroller
    Dockerfile 究极打包 Centos7+python3.10.6
    【Java笔试强训】Day1(100449-组队竞赛 、OR63 删除公共字符)
    【数据结构(三)】单向环形链表和约瑟夫问题(3)
    推荐系统 推荐算法 (小红书为例) 笔记 2
    es重启临时关闭自动分片
    Scala的模式匹配与样例类
    【FPGA教程案例51】控制案例3——基于FPGA的PWM波形产生verilog实现
    原始值的响应式方案
    赋安消防主机FS5050,波特率20k,单模单芯SC接头,9-36V直流供电的光纤联网方式之一
  • 原文地址:https://blog.csdn.net/qq_35554617/article/details/132635647