使用Qt调用windows api中的setupapi.h库中的SetupDiGetClassDevsSetupDiEnumDeviceInfo函数获取设备管理器中的设备列表结构,并获取设备的描述,图标,类名,guid等.(Windows系统环境)

实现效果

通过windows api获取本地计算机设备信息元素,
仿照设备管理器的样子加载到目录树控件上。涉及到对电脑设备信息的读取。
在这里插入图片描述

库引用

使用SetupAPI库中的函数获取包含本地计算机请求的设备信息元素的设备信息

#include <Windows.h>
#include <initguid.h> //LNK2001: 无法解析的外部符号 
#include <SetupAPI.h>
#pragma comment(lib,"SetupAPI")
#include <devpkey.h>
#include <devguid.h>
#include <guiddef.h>

如果使用DEFINE_DEVPROPKEY,一定要加上<initguid.h>,不然会出现无法解析的外部符号错误.
#include <initguid.h> //解决 error: LNK2001: 无法解析的外部符号 DEVPKEY_Device_DriverInfPath <devpkey.h>

相关函数的说明

  • SetupDiGetClassDevs 函数

SetupDiGetClassDevs 函数返回包含本地计算机请求的设备信息元素的设备信息集的句柄
语法:

//! 如果操作成功, SetupDiGetClassDevs 将返回 设备信息集 的句柄,该信息集包含与所提供的参数匹配的所有已安装设备。 如果操作失败,函数将返回INVALID_HANDLE_VALUE
WINSETUPAPI HDEVINFO SetupDiGetClassDevsW(
  [in, optional] const GUID *ClassGuid, //指向设备安装类或设备接口类的 GUID 的指针。 此指针是可选的,可以为 NULL
  [in, optional] PCWSTR     Enumerator, //指向以 NULL 结尾的字符串的指针
  [in, optional] HWND       hwndParent,//顶级窗口的句柄,用于与在设备信息集中安装设备实例关联的用户界面。 此句柄是可选的,可以为 NULL。
  [in]           DWORD      Flags //DWORD 类型的变量,指定用于筛选添加到设备信息集的设备信息元素的控制选项
);
  • SetupDiEnumDeviceInfo 函数

SetupDiEnumDeviceInfo 函数返回一个SP_DEVINFO_DATA结构,该结构指定设备信息集中的设备信息元素。
语法:

//! 如果成功,该函数将返回 TRUE 。 否则,它将返回 FALSE ,并且可以通过调用 GetLastError 来检索记录的错误。
WINSETUPAPI BOOL SetupDiEnumDeviceInfo(
  [in]  HDEVINFO         DeviceInfoSet, //设备信息集的句柄,为其返回表示设备信息元素的SP_DEVINFO_DATA结构。
  [in]  DWORD            MemberIndex, //要检索的设备信息元素的从零开始的索引。
  [out] PSP_DEVINFO_DATA DeviceInfoData //指向 SP_DEVINFO_DATA 结构的指针,用于接收有关枚举设备信息元素的信息
);
  • SetupDiBuildClassInfoList 函数

SetupDiBuildClassInfoList 函数返回用于标识本地计算机上安装的类的安装程序类 GUID 的列表。
语法:

//! 如果成功,该函数将返回 TRUE 。 否则,它将返回 FALSE ,并且可以通过调用 GetLastError 来检索记录的错误。
WINSETUPAPI BOOL SetupDiBuildClassInfoList(
  [in]            DWORD  Flags,  //用于控制列表中类的排除的标志。 如果未指定标志,则所有安装类都包含在列表中
  [out, optional] LPGUID ClassGuidList,  //指向 GUID 类型的数组的指针,该数组接收安装程序类 GUID 的列表
  [in]            DWORD  ClassGuidListSize, //ClassGuildList 参数指向的数组中的 GUID 数。 如果 ClassGuidList 为 NULL, 则 ClassGuidSize 必须为零。
  [out]           PDWORD RequiredSize 
  //指向 DWORD 类型变量的指针,该变量接收返回 (的 GUID 数(如果数字小于或等于 ClassGuidList 参数) 指向的数组的大小(以 GUID 为单位)。
 //如果此数字大于 ClassGuidList 数组的大小,则指示 ClassGuidList 数组必须有多大才能包含所有类 GUID。
);
  • SetupDiGetClassDescription 函数

SetupDiGetClassDescription 函数检索与指定的安装程序类 GUID 关联的类说明。
语法:

//! 如果成功,函数将返回 TRUE 。 否则,它将返回 FALSE
WINSETUPAPI BOOL SetupDiGetClassDescriptionW(
  [in]            const GUID *ClassGuid, //要检索其说明的安装程序类的 GUID。
  [out]           PWSTR      ClassDescription, //指向接收类说明的字符缓冲区的指针。
  [in]            DWORD      ClassDescriptionSize, //ClassDescription 缓冲区的大小(以字符为单位)。
  [out, optional] PDWORD     RequiredSize //指向类型为 DWORD 的变量的指针,该变量接收存储类说明所需的大小(以字符为单位), (包括 NULL 终止符) 。 RequiredSize 始终小于 LINE_LEN。 此参数是可选的,可以为 NULL。
);

代码示例

  • 获取已安装的设备管理器类的GUID

通过 SetupDiBuildClassInfoList 获取电脑上已安装的所有设备管理器类的GUID列表指针,通过类的GUID可以获取到设备实例
注意:在声明GUID内存大小时,需要返回的数量+1,要不然获取失败!

GetSetupDiBuildClassInfoList(LPGUID& ClassGuidList)const
{
    DWORD RequiredSize=0;
    LPGUID guid_list = NULL;
    DWORD size=0;

    bool ret=SetupDiBuildClassInfoList(0,NULL,0,&RequiredSize);
    if(RequiredSize>0)
    {
        // 分配足够大的缓冲区
        // 分配内存时必须多加一 否则异常
        ClassGuidList = (GUID*)malloc((RequiredSize+1)*sizeof (GUID) );
        ret=SetupDiBuildClassInfoList(0,ClassGuidList,RequiredSize,&size);
        if(!ret)
            RequiredSize=0;
    }
}

可以参考纯C++写的其他示例(需要翻墙):
https://cpp.hotexamples.com/examples/-/-/SetupDiBuildClassInfoList/cpp-setupdibuildclassinfolist-function-examples.html

  • 获取设备管理器中设备实例列表

根据SetupDiBuildClassInfoList获取的guid列表,通过SetupDiGetClassDevs
SetupDiEnumDeviceInfo函数获取电脑中设备管理器实例。并打印设备描述。

LPGUID ClassGuidList= NULL;
    int RequiredSize= GetSetupDiBuildClassInfoList( ClassGuidList);
    if(RequiredSize>0)
    {
        qDebug()<<"[已安装设备] !!!";
        for(int i=0;i<RequiredSize;i++)
        {
            PWSTR ClassName=new WCHAR[MAX_CLASS_NAME_LEN];
            if(SetupDiGetClassDescription(&ClassGuidList[i],ClassName,MAX_CLASS_NAME_LEN,NULL))
            {
                qDebug()<<"["<<i<<"] "<<QString::fromWCharArray(ClassName);
                //qDebug()<<"ICON: "<<GeticonPath(&ClassGuidList[i]);
                qDebug()<<"GUID: "<<QString::fromWCharArray(guid_to_wstring(ClassGuidList[i]));
                //SetupDiGetClassDevs 函数返回包含本地计算机请求的设备信息元素的设备信息集的句柄。
                HDEVINFO deviceInfoSet = SetupDiGetClassDevs(&ClassGuidList[i], NULL, NULL, DIGCF_PRESENT);
                if (deviceInfoSet == INVALID_HANDLE_VALUE) {
                    qDebug("Failed to get device information set. Error code: %d\n", GetLastError());
                    continue ;
                }

                DWORD requiredSize=0;
                SP_DEVINFO_DATA deviceInfoData;
                deviceInfoData.cbSize=sizeof(SP_DEVINFO_DATA);
                for (DWORD i = 0; SetupDiEnumDeviceInfo(deviceInfoSet, i, &deviceInfoData); i++) {
					//获取其他业务值
//                    PBYTE buffer=new BYTE [MAX_PATH];
//                    if(GetSetupDiGetDeviceProperty(deviceInfoSet,
//                                                   &deviceInfoData,
//                                                   DEVPROP_TYPE_STRING ,
//                                                   &DEVPKEY_NAME ,
//                                                   buffer,requiredSize))
//                    {
//                        qDebug()<<"---------"<<QString::fromWCharArray((TCHAR*)buffer);
//                    }

//                    PBYTE Guidbuffer=new BYTE [MAX_PATH];
//                    if(GetSetupDiGetDeviceProperty(deviceInfoSet,
//                                                   &deviceInfoData,
//                                                   DEVPROP_TYPE_GUID ,
//                                                   &DEVPKEY_Device_ClassGuid ,
//                                                   Guidbuffer,requiredSize))
//                    {
//                        GUID* classguid=(GUID*)Guidbuffer;
//                        qDebug()<<"--------- GUID: "<<QString::fromWCharArray(guid_to_wstring(*classguid));
//                    }
//                    else
//                        qDebug()<<"[Guidbuffer] Is Failed!";


                }

                // 清理:销毁设备信息集
                SetupDiDestroyDeviceInfoList(deviceInfoSet);
            }

        }
    }

打印设备描述与对应guid内容:
1.这里的数据只是我测试电脑上安装的设备,不包括所有设备类!
2.设备类的guid通用,在其他电脑上也显示的一样的值!可以通过guid直接获取某个设备实例

[已安装设备] !!!
[ 0 ]  "Xbox 外设"
GUID:  "{05F5CFE2-4733-4950-A6BB-07AAD01A3A84}"
[ 1 ]  "POS 远程设备"
GUID:  "{13E42DFA-85D9-424D-8646-28A70F864F9C}"
[ 2 ]  "数字媒体设备"
GUID:  "{14B62F50-3F15-11DD-AE16-0800200C9A66}"
[ 3 ]  "打印队列"
GUID:  "{1ED2BBF9-11F0-4084-B21F-AD83A8E6DCDC}"
[ 4 ]  "移动设备"
GUID:  "{25DBCE51-6C8F-4A72-8A6D-B54C2B4FC835}"
[ 5 ]  "安全加速器"
GUID:  "{268C95A1-EDFE-11D3-95C3-0010DC4050A5}"
[ 6 ]  "POS HID 磁条阅读器设备"
GUID:  "{2A9FE532-0CDC-44F9-9827-76192F2CA2FB}"
[ 7 ]  "FS 系统恢复筛选器"
GUID:  "{2DB15374-706E-4131-A0C7-D7C78EB0289A}"
[ 8 ]  "通用串行总线控制器"
GUID:  "{36FC9E60-C465-11CF-8056-444553540000}"
[ 9 ]  "FS 内容筛选过滤器"
GUID:  "{3E3F0674-C83C-4558-BB26-9820E1EBA5C5}"
[ 10 ]  "Media Center Extenders"
GUID:  "{43675D81-502A-4A82-9F84-B75F418C5DEA}"
[ 11 ]  "IEEE 1394 和 SCSI 打印机"
GUID:  "{4658EE7E-F050-11D1-B6BD-00C04FA372A7}"
[ 12 ]  "IEEE 1284.4 设备"
GUID:  "{48721B56-6795-11D2-B1A8-0080C72E74A2}"
[ 13 ]  "FS 复制筛选器"
GUID:  "{48D3EBC4-4CF8-48FF-B869-9C68AD42EB9F}"
[ 14 ]  "IEEE 1284.4 兼容打印机"
GUID:  "{49CE6AC8-6F86-11D2-B1E5-0080C72E74A2}"
[ 15 ]  "DVD/CD-ROM 驱动器"
GUID:  "{4D36E965-E325-11CE-BFC1-08002BE10318}"
[ 16 ]  "计算机"
GUID:  "{4D36E966-E325-11CE-BFC1-08002BE10318}"
[ 17 ]  "磁盘驱动器"
GUID:  "{4D36E967-E325-11CE-BFC1-08002BE10318}"
[ 18 ]  "显示适配器"
GUID:  "{4D36E968-E325-11CE-BFC1-08002BE10318}"
[ 19 ]  "软盘驱动器控制器"
GUID:  "{4D36E969-E325-11CE-BFC1-08002BE10318}"
[ 20 ]  "IDE ATA/ATAPI 控制器"
GUID:  "{4D36E96A-E325-11CE-BFC1-08002BE10318}"
[ 21 ]  "键盘"
GUID:  "{4D36E96B-E325-11CE-BFC1-08002BE10318}"
[ 22 ]  "声音、视频和游戏控制器"
GUID:  "{4D36E96C-E325-11CE-BFC1-08002BE10318}"
[ 23 ]  "调制解调器"
GUID:  "{4D36E96D-E325-11CE-BFC1-08002BE10318}"
[ 24 ]  "监视器"
GUID:  "{4D36E96E-E325-11CE-BFC1-08002BE10318}"
[ 25 ]  "鼠标和其他指针设备"
GUID:  "{4D36E96F-E325-11CE-BFC1-08002BE10318}"
[ 26 ]  "内存技术设备"
GUID:  "{4D36E970-E325-11CE-BFC1-08002BE10318}"
[ 27 ]  "多功能适配器"
GUID:  "{4D36E971-E325-11CE-BFC1-08002BE10318}"
[ 28 ]  "网络适配器"
GUID:  "{4D36E972-E325-11CE-BFC1-08002BE10318}"
[ 29 ]  "网络客户端"
GUID:  "{4D36E973-E325-11CE-BFC1-08002BE10318}"
[ 30 ]  "Network Service"
GUID:  "{4D36E974-E325-11CE-BFC1-08002BE10318}"
[ 31 ]  "网络协议"
GUID:  "{4D36E975-E325-11CE-BFC1-08002BE10318}"
[ 32 ]  "PCMCIA 适配器"
GUID:  "{4D36E977-E325-11CE-BFC1-08002BE10318}"
[ 33 ]  "端口 (COM 和 LPT)"
GUID:  "{4D36E978-E325-11CE-BFC1-08002BE10318}"
[ 34 ]  "打印机"
GUID:  "{4D36E979-E325-11CE-BFC1-08002BE10318}"
[ 35 ]  "存储控制器"
GUID:  "{4D36E97B-E325-11CE-BFC1-08002BE10318}"
[ 36 ]  "系统设备"
GUID:  "{4D36E97D-E325-11CE-BFC1-08002BE10318}"
[ 37 ]  "其他设备"
GUID:  "{4D36E97E-E325-11CE-BFC1-08002BE10318}"
[ 38 ]  "软盘驱动器"
GUID:  "{4D36E980-E325-11CE-BFC1-08002BE10318}"
[ 39 ]  "POS Line Display"
GUID:  "{4FC9541C-0FE6-4480-A4F6-9495A0D17CD2}"
[ 40 ]  "处理器"
GUID:  "{50127DC3-0F36-415E-A6CC-4CB3BE910B65}"
[ 41 ]  "多串口适配器"
GUID:  "{50906CB8-BA12-11D1-BF5D-0000F805F530}"
[ 42 ]  "内存设备"
GUID:  "{5099944A-F6B9-4057-A056-8C550228544C}"
[ 43 ]  "智能卡读卡器"
GUID:  "{50DD5230-BA8A-11D1-BF5D-0000F805F530}"
[ 44 ]  "传感器"
GUID:  "{5175D334-C371-4806-B3BA-71FD53C9258D}"
[ 45 ]  "存储卷卷影副本"
GUID:  "{533C5B84-EC70-11D2-9505-00C04F79DEAF}"
[ 46 ]  "叠瓦式磁记录盘"
GUID:  "{53487C23-680F-4585-ACC3-1F10D6777E82}"
[ 47 ]  "永久性存储磁盘"
GUID:  "{53966CB1-4D46-4166-BF23-C522403CD495}"
[ 48 ]  "叠瓦式磁记录盘卷"
GUID:  "{53B3CF03-8F5A-4788-91B6-D19ED9FCCCBF}"
[ 49 ]  "存储类内存卷"
GUID:  "{53CCB149-E543-4C84-B6E0-BCE4F6B7E806}"
[ 50 ]  "生物识别设备"
GUID:  "{53D29EF7-377C-4D14-864B-EB3A85769359}"
[ 51 ]  "邻近感应设备"
GUID:  "{5630831C-06C9-4856-B327-F5D32586E060}"
[ 52 ]  "音频处理对象(APO)"
GUID:  "{5989FCE8-9CD0-467D-8A6A-5419E31529D4}"
[ 53 ]  "OPOS 旧设备"
GUID:  "{5AEA001D-9372-4ED7-97F3-B79BF15A53C5}"
[ 54 ]  "软件组件"
GUID:  "{5C4C3332-344D-483C-8739-259E934C9CC8}"
[ 55 ]  "FS 系统筛选器"
GUID:  "{5D1B9AAA-01E2-46AF-849F-272B3F324C46}"
[ 56 ]  "软件设备"
GUID:  "{62F9C741-B25A-46CE-B54C-9BCCCE08B6F2}"
[ 57 ]  "FS 物理配额管理筛选器"
GUID:  "{6A0A8E78-BBA6-4FC4-A709-1E33CD09D67E}"
[ 58 ]  "IEEE 1394 主控制器"
GUID:  "{6BDD1FC1-810F-11D0-BEC7-08002BE2092F}"
[ 59 ]  "红外线设备"
GUID:  "{6BDD1FC5-810F-11D0-BEC7-08002BE2092F}"
[ 60 ]  "图像设备"
GUID:  "{6BDD1FC6-810F-11D0-BEC7-08002BE2092F}"
[ 61 ]  "磁带驱动器"
GUID:  "{6D807884-7D21-11CF-801C-08002BE10318}"
[ 62 ]  "存储卷"
GUID:  "{71A27CDD-812A-11D0-BEC7-08002BE2092F}"
[ 63 ]  "FS 连续备份筛选器"
GUID:  "{71AA14F8-6FAD-4622-AD77-92BB9D7E6947}"
[ 64 ]  "电池"
GUID:  "{72631E54-78A4-11D0-BCF7-00AA00B7B32A}"
[ 65 ]  "人机接口设备"
GUID:  "{745A17A0-74D3-11D0-B6FE-00A0C90F57DA}"
[ 66 ]  "POS Cash Drawer"
GUID:  "{772E18F2-8925-4229-A5AC-6453CB482FDA}"
[ 67 ]  "61883 设备"
GUID:  "{7EBEFBC0-3200-11D2-B4C2-00A0C9697D07}"
[ 68 ]  "FS 配额管理筛选器"
GUID:  "{8503C911-A6C7-4919-8F79-5028F5866B0C}"
[ 69 ]  "通用网络驱动器"
GUID:  "{87EF9AD1-8F70-49EE-B215-AB1FCADCBE3C}"
[ 70 ]  "通用远程桌面设备"
GUID:  "{88A1C342-4539-11D3-B88D-00C04FAD5171}"
[ 71 ]  "通用串行总线设备"
GUID:  "{88BAE032-5A81-49F0-BC3D-A4FF138216D6}"
[ 72 ]  "FS 复制保护筛选器"
GUID:  "{89786FF1-9C12-402F-9C9E-17753C7F4375}"
[ 73 ]  "非即插即用驱动程序"
GUID:  "{8ECC055D-047F-11D1-A537-0000F8753ED1}"
[ 74 ]  "智能卡"
GUID:  "{990A2BD7-E738-46C7-B26F-1CF8FB9F1391}"
[ 75 ]  "IEEE 1667 接收器和控制设备"
GUID:  "{9DA2B80F-F89F-4A49-A5C2-511B085B9E8A}"
[ 76 ]  "SD 主适配器"
GUID:  "{A0A588A4-C46F-4B37-B7EA-C82FE89870C6}"
[ 77 ]  "FS 加密筛选器"
GUID:  "{A0A701C0-A511-42FF-AA6C-06DC0395576F}"
[ 78 ]  "FS 防病毒筛选器"
GUID:  "{B1D1A169-C54F-4379-81DB-BEE7D88D7454}"
[ 79 ]  "远程桌面摄像头设备"
GUID:  "{B2728D24-AC56-42DB-9E02-8EDAF5DB652F}"
[ 80 ]  "FS 活动监控筛选器"
GUID:  "{B86DFF51-A31E-4BAC-B3CF-E8CFE75C9FC2}"
[ 81 ]  "通用串行总线功能控制器"
GUID:  "{BBBE8734-08FA-4966-B6A6-4E5AD010CDD7}"
[ 82 ]  "音频/视频控制设备"
GUID:  "{C06FF265-AE09-48F0-812C-16753D7CBA83}"
[ 83 ]  "音频输入和输出"
GUID:  "{C166523C-FE0C-4A94-A586-F1A80CFBBF3E}"
[ 84 ]  "POS Barcode Scanner"
GUID:  "{C243FFBD-3AFC-45E9-B3D3-2BA18BC7EBC5}"
[ 85 ]  "WSD 打印提供程序"
GUID:  "{C30ECEA0-11EF-4EF9-B02E-6AF81E6E65C0}"
[ 86 ]  "POS Receipt Printer"
GUID:  "{C7BC9B22-21F0-4F0D-9BB6-66C229B8CD33}"
[ 87 ]  "照相机"
GUID:  "{CA3E7AB9-B4C3-4AE6-8251-579EF933890F}"
[ 88 ]  "FS CFS 元数据服务器筛选器"
GUID:  "{CDCF0939-B75B-4630-BF76-80F7BA655884}"
[ 89 ]  "媒体更换器设备"
GUID:  "{CE5939AE-EBDE-11D0-B181-0000F8753EC4}"
[ 90 ]  "FS 安全性增强器筛选器"
GUID:  "{D02BC3DA-0C8E-4945-9BD5-F1883C226C8C}"
[ 91 ]  "Miracast 显示设备"
GUID:  "{D421B08E-6D16-41CA-9C4D-9147E5AC98E0}"
[ 92 ]  "SBP2 IEEE 1394 设备"
GUID:  "{D48179BE-EC20-11D1-B6B8-00C04FA372A7}"
[ 93 ]  "FS HSM 筛选器"
GUID:  "{D546500A-2AEB-45F6-9482-F4B1799C3177}"
[ 94 ]  "Xbox 360 外设"
GUID:  "{D61CA365-5AF4-4486-998B-9DB4734C6CA3}"
[ 95 ]  "安全设备"
GUID:  "{D94EE5D8-D189-4994-83D2-F68D7D41B0E6}"
[ 96 ]  "智能卡筛选器"
GUID:  "{DB4F6DDD-9C0E-45E4-9597-78DBBAD0F412}"
[ 97 ]  "蓝牙"
GUID:  "{E0CBF06C-CD8B-4647-BB8A-263B43F0F974}"
[ 98 ]  "扩展"
GUID:  "{E2F84CE7-8EFA-411C-AA69-97454CA4CB57}"
[ 99 ]  "FS 基础结构筛选器"
GUID:  "{E55FA6F9-128C-4D04-ABAB-630C74B1453A}"
[ 100 ]  "USB 连接器管理器"
GUID:  "{E6F1AA1C-7F3B-4473-B2E8-C97D8AC71D53}"
[ 101 ]  "便携设备"
GUID:  "{EEC5AD98-8080-425F-922A-DABF3DE3F69A}"
[ 102 ]  "Compute accelerators"
GUID:  "{F01A9D53-3FF6-48D2-9F97-C8A7004BE10C}"
[ 103 ]  "固件"
GUID:  "{F2E7DD72-6468-4E36-B6F1-6488F42C1B52}"
[ 104 ]  "FS 压缩筛选器"
GUID:  "{F3586BAF-B5AA-49B5-8D6C-0569284C639F}"
[ 105 ]  "FS 虚拟化筛选器"
GUID:  "{F75A86C0-10D8-4C3A-B233-ED60E4CDFAAC}"
[ 106 ]  "FS 打开文件备份筛选器"
GUID:  "{F8ECAFA6-66D1-41A5-899B-66585D7216B7}"
[ 107 ]  "FS 撤消删除筛选器"
GUID:  "{FE8F1572-C67A-48C0-BBAC-0B5C6D66CAFB}"
  • 使用CM_Get_Class_Property 获取 设备安装类的图标路径

使用CM_Get_Class_PropertyDEVPKEY_DeviceClass_IconPath获取设备安装类的图标路径,也可以用 SetupDiGetClassProperty 来检索 DEVPKEY_DeviceClass_IconPath 的值。

//! 例:"%SystemRoot%\\System32\\setupapi.dll,-159"
GeticonPath(LPCGUID ClassGUID)
{
    QString iconpath;
    CONFIGRET result;
    ULONG deviceIconPathLength= 0x40;
    DEVPROPTYPE deviceIconPathPropertyType;
    PBYTE deviceIconPath=new BYTE [deviceIconPathLength];

    if ((result = CM_Get_Class_Property(
           ClassGUID,
           &DEVPKEY_DeviceClass_IconPath,
           &deviceIconPathPropertyType,
           deviceIconPath,
           &deviceIconPathLength,
           0
           )) != CR_SUCCESS)
       {
           deviceIconPath = new BYTE [deviceIconPathLength];

           result = CM_Get_Class_Property(
               ClassGUID,
               &DEVPKEY_DeviceClass_IconPath,
               &deviceIconPathPropertyType,
               deviceIconPath,
               &deviceIconPathLength,
               0
               );
       }

      if (result == CR_SUCCESS)
       {
          iconpath=QString::fromWCharArray((TCHAR*)deviceIconPath);
//          qDebug()<<"deviceIconPath : "<<iconpath;
       }
      else
      {
          qDebug()<<"CM_Get_Class_Property is faile!";
      }
    free(deviceIconPath);
    return iconpath;
}

其他示例(需要翻墙):
https://cpp.hotexamples.com/examples/-/-/CM_Get_Class_Property/cpp-cm_get_class_property-function-examples.html

  • 从包含环境变量路径中获取完整路径

将包含环境变量的路径:
%SystemRoot%\\System32\\setupapi.dll
转换成绝对路径:
C:\\Windows\\System32\\setupapi.dll
涉及到GetEnvironmentVariable函数和正则表达式的使用

static QString Get_Full_Paths(QString path)
    {
        auto getSystempath=[&](QString path)->QString{
            TCHAR systemRoot[MAX_PATH];
            DWORD size = sizeof(systemRoot) / sizeof(TCHAR);
            if (GetEnvironmentVariable(utf8_to_wchar(path.toStdString().c_str()), systemRoot, size) > 0)
            {
                return QString::fromWCharArray(systemRoot);
            }
            return path;
        };

        QString Strpath=path;
        QRegExp regExp("%([^%]+)%");
        int pos = regExp.indexIn(path);
        for(int i=0;i<regExp.captureCount();i++)
        {
            QString match= regExp.cap(i);
            Strpath=Strpath.replace(QString("%%1%").arg(match),getSystempath(match.replace("%","")));
        }
        return Strpath;
    }

将类的GUID转换为字符串

通过StringFromGUID2函数将GUID转换为字符串

wchar_t* guid_to_wstring(GUID guid)
{
    // 分配足够的空间来存储GUID的字符串表示形式
    wchar_t* GUIDSTR=new  wchar_t [MAX_PATH]; // 38个字符的GUID加上一个终止null字符
    // 将GUID转换为字符串
    if (StringFromGUID2(guid, GUIDSTR, MAX_PATH) == 0) {
        std::wcerr << L"Failed to convert GUID to string." << std::endl;
        GUIDSTR=(wchar_t*)L"NULL";
    }
    return GUIDSTR;
}

获取源码

文章示例展示了相关函数的完整用法,如果你想直观地的了解函数使用,省时省力,
你可以打赏作者,获取本章示例源码
->(Qt案例 调用WINDOWS API中的SETUPAPI.H库获取设备管理器中设备的详细信息 示例项目源代码)

源码使用Qt Creator5.13 MSCV2017 64X编译
请添加图片描述

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐