Qt Windows 环境读取注册表快速获取可用串口设备

使用Qt做一些串口上位机开发时,发现使用Qt自带的QSerialPortInfo来获取当前可用串口设备时很慢,还可能导致GUI界面卡住,所以尝试使用windows api直接读取注册表来获取可用串口,非常快。

通过Qt自带QSerialPortInfo获取当前可用串口

#include <QSerialPort>
#include <QSerialPortInfo>
QStringList SerialServer::getAvailableSerialPort()
{
    QStringList portNameList;			//可用串口
    foreach(const QSerialPortInfo &info,QSerialPortInfo::availablePorts()){
    QSerialPort serial;
    serial.setPort(info);
    if(serial.open(QIODevice::ReadWrite)){
        portNameList.push_back(serial.portName());
        serial.close();
    } else serial.close();
    if(portNameList.size()==0){
        QMessageBox::information(NULL,"ERROR","Serial port not available");
    }
    return portNameList;
}

通过读取Windows 注册表获取当前可用串口

#include <QSettings>
#include <qt_windows.h>

//获取串口列表函数
QStringList SerialServer::getAvailableSerialPort()
{
    QStringList availablePortName;
    if(m_serial->isOpen()){
        this->close();
    }
    if(m_serial != NULL){
        QString path = "HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM";//注册表路径
        QSettings *settings = new QSettings(path, QSettings::NativeFormat);
        QStringList key = settings->allKeys();
        for(int i = 0;i<key.size();i++){
            QString key = getPortName(i,"key");
            QString value = getPortName(i,"value");
            qDebug()<<key<<value;
            availablePortName<<value;
        }
    }
    availableSerialPortName = availablePortName;
    return availablePortName;
}

QString SerialServer::getPortName(int index, QString keyorvalue)
{
    QString 	commresult;
    HKEY        hKey;
    wchar_t     keyname[256]; //键名数组
    char        keyvalue[256];  //键值数组
    DWORD       keysize,type,valuesize;
    if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, TEXT("HARDWARE\\DEVICEMAP\\SERIALCOMM"), 0, KEY_READ, &hKey) != 0) {
        QString error="Cannot open regedit!";   //无法打开注册表时返回error
        return error;
    }
    QString keymessage;//键名
    QString message;
    QString valuemessage;//键值
    keysize = sizeof(keyname);
    valuesize = sizeof(keyvalue);
    if (RegEnumValue(hKey, index, keyname, &keysize, 0, &type, (BYTE*)keyvalue, &valuesize) == 0) { //列举键名和值
        for (int i=0; i<(int)keysize; i++) {
            message = keyname[i];
            keymessage.append(message);
        }
        for (int j=0; j<(int)valuesize; j++) {
            if (keyvalue[j] != 0x00) {
                valuemessage.append(keyvalue[j]);
            }
        }
        if (keyorvalue == "key") {
            commresult = keymessage;
        }
        if (keyorvalue == "value") {
            commresult=valuemessage;
        }
    } else {
        commresult = "nokey";
    }
    RegCloseKey(hKey);//关闭注册表
    return commresult;
}

posted @ 2020-12-08 18:32  chunchun_studio  阅读(597)  评论(0)    收藏  举报