Qt篇——获取Windows系统上插入的串口设备的物理序号

        先右键【此电脑-管理- 设备管理器-端口(COM和LPT)】中找到我们插入的某个设备的物理序号,如下图红色矩形框出的信息,这个就是已插入设备的物理序号(就是插在哪个USB口的意思)。

        在Linux下我们可以通过往/etc/udev/rules.d文件夹中放入串口绑定规则文件,将指定物理序号devpath上的设备绑定一个固定名称(参考我的文章Linux绑定串口名称),而在windows下没有这种方式。

        那么当我们在Qt开发过程中,需要获取windows系统下特定物理USB口的序号(如Port_#0001.Hub_#0002)和串口名称(如COM3),把它作为某个设备的专用启动位置,就可以按下面的方法得到(我用的Qt5.14.2,是直接可以用的,这是windows的api,理论上受Qt版本影响不大)。 (QSerialPort本身不提供相关的接口,所以我们要使用windows api)。

#include <windows.h>
#include <setupapi.h>
#include <regstr.h>

// 定义全局变量
GUID GuidSerialPort = { 0x4d36e978, 0xe325, 0x11ce, { 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 } };

// 使用SetupDiGetDeviceRegistryProperty获取设备属性
bool GetDeviceProperty(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, DWORD Property, LPWSTR Buffer, DWORD BufferLength, PDWORD RequiredSize) {
    DWORD DataT;
    LONG Result;

    DeviceInfoData->cbSize = sizeof(SP_DEVINFO_DATA);

    // 获取属性
    Result = SetupDiGetDeviceRegistryPropertyW(DeviceInfoSet, DeviceInfoData, Property, &DataT, (PBYTE)Buffer, BufferLength, RequiredSize);

    if (Result) {
        return true;
    } else {
        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
            return false;
        } else {
            return false;
        }
    }
}

void serialPortListFresh(){
    HDEVINFO DeviceInfoSet = INVALID_HANDLE_VALUE;
    SP_DEVINFO_DATA DeviceInfoData;
    DWORD i;
    WCHAR Buffer[256];
    DWORD RequiredSize;
    QString portName;
    QString locationInfo;

    DeviceInfoSet = SetupDiGetClassDevs(&GuidSerialPort, 0, 0, DIGCF_PRESENT);
    if (DeviceInfoSet == INVALID_HANDLE_VALUE) {
        qDebug() << "Error getting device information set";
    }

    for (i = 0; i < 10; i++) {
        // 清空缓冲区
        ZeroMemory(Buffer, sizeof(Buffer));
        RequiredSize = sizeof(Buffer);

        // 获取设备实例路径
        if (GetDeviceProperty(DeviceInfoSet, &DeviceInfoData, SPDRP_LOCATION_INFORMATION, Buffer, sizeof(Buffer), &RequiredSize)) {
            locationInfo = QString::fromWCharArray(Buffer);
            qDebug() << "Location Info:" << locationInfo;

            // 获取设备描述(通常是串口名,如"COM1")
            ZeroMemory(Buffer, sizeof(Buffer));
            RequiredSize = sizeof(Buffer);
            if (GetDeviceProperty(DeviceInfoSet, &DeviceInfoData, SPDRP_DEVICEDESC, Buffer, sizeof(Buffer), &RequiredSize)) {
                portName = QString::fromWCharArray(Buffer);
                qDebug() << "Port Name:" << portName;

                // 输出配对信息
                qDebug() << portName << " is located at" << locationInfo;
            }
            if (GetDeviceProperty(DeviceInfoSet, &DeviceInfoData, SPDRP_FRIENDLYNAME, Buffer, sizeof(Buffer), &RequiredSize)) {
                portName = QString::fromWCharArray(Buffer);
                qDebug() << "Port Name:" << portName << "\n";
                QString portCom = portName.mid(portName.indexOf("("), portName.indexOf(")") - portName.indexOf("("));
                //portCom 就是串口号,比如COM3
            }
        }

        if (!SetupDiEnumDeviceInfo(DeviceInfoSet, i, &DeviceInfoData)) {
            break;
        }
    }

    SetupDiDestroyDeviceInfoList(DeviceInfoSet);

}

可以得到如下打印:

这样我们就知道插到Port_#0001.Hub_#0002(举例)的USB口上的设备的端口号是COM3了,那么接下来就可以用QSerialPort打开COM3设备进行通信了。

注:更多串口信息参数详见微软官网:

SetupDiGetDeviceRegistryPropertyA 函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

易Yi

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

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

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

打赏作者

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

抵扣说明:

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

余额充值