C++ 检测Windows上所有可用串行端口的正确方法是什么?

C++ 检测Windows上所有可用串行端口的正确方法是什么?,c++,c,windows,serial-port,C++,C,Windows,Serial Port,在Windows下列出串行端口有几种方法,但我不确定正确的方法是什么:检测所有可用串行端口的方法 一个很好的代码示例是-其中有9个!列举串行设备的方法 问题是:做这件事的最佳方式是什么 要求: 不打开端口以检查它们是否可用。 能够检测与COMx名称不同的端口。 在Windows XP SP2或更高版本上工作 串口是非常简单的设备,可以追溯到石器时代的计算硬件。他们不支持即插即用,无法判断是否有人插入了设备。您唯一能做的就是发现哪些端口可用,SerialPort.GetPortNames返回列表。

在Windows下列出串行端口有几种方法,但我不确定正确的方法是什么:检测所有可用串行端口的方法

一个很好的代码示例是-其中有9个!列举串行设备的方法

问题是:做这件事的最佳方式是什么

要求:

不打开端口以检查它们是否可用。 能够检测与COMx名称不同的端口。 在Windows XP SP2或更高版本上工作
串口是非常简单的设备,可以追溯到石器时代的计算硬件。他们不支持即插即用,无法判断是否有人插入了设备。您唯一能做的就是发现哪些端口可用,SerialPort.GetPortNames返回列表。一些USB仿真器可以生成与端口名匹配的描述性名称,您可以使用WMI、Win32_SerialPort类发现这些名称


这些都不能帮助您发现连接到特定设备的COM端口。只有一个人知道,她用身体将电缆插入连接器。您需要提供一个配置UI,让用户选择端口号。一个组合框完成任务。将所选内容保存在配置数据中,下次程序启动时,设备很可能仍连接到同一端口。

如果可以访问注册表,HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM键包含Windows在某些情况下当前支持的COM端口列表,该信息可能陈旧/不正确;我怀疑,当提供串行端口的即插即用设备未完成检测/安装或最近被移除时

void SelectComPort() //added function to find the present serial 
{

    TCHAR lpTargetPath[5000]; // buffer to store the path of the COMPORTS
    DWORD test;
    bool gotPort=0; // in case the port is not found

    for(int i=0; i<255; i++) // checking ports from COM0 to COM255
    {
        CString str;
        str.Format(_T("%d"),i);
        CString ComName=CString("COM") + CString(str); // converting to COM0, COM1, COM2

        test = QueryDosDevice(ComName, (LPSTR)lpTargetPath, 5000);

            // Test the return value and error if any
        if(test!=0) //QueryDosDevice returns zero if it didn't find an object
        {
            m_MyPort.AddString((CString)ComName); // add to the ComboBox
            gotPort=1; // found port
        }

        if(::GetLastError()==ERROR_INSUFFICIENT_BUFFER)
        {
            lpTargetPath[10000]; // in case the buffer got filled, increase size of the buffer.
            continue;
        }

    }

    if(!gotPort) // if not port
    m_MyPort.AddString((CString)"No Active Ports Found"); // to display error message incase no ports found

}

这是.NET Framework的方法报告可用COM端口的方式,上述信息来自链接页面。

这是@michael jacob mathew答案的现代化版本:

CUIntArray ports;
EnumerateSerialPorts(ports);

for (int i = 0; i<ports.GetSize(); i++)
{
    CString str;
    str.Format(_T("COM%d"), ports.ElementAt(i));
    m_ctlPort.AddString(str);
}
#include <iostream>
#include <string>
#include <Windows.h>

bool SelectComPort() //added function to find the present serial 
{
    char lpTargetPath[5000]; // buffer to store the path of the COMPORTS
    bool gotPort = false; // in case the port is not found

    for (int i = 0; i < 255; i++) // checking ports from COM0 to COM255
    {
        std::string str = "COM" + std::to_string(i); // converting to COM0, COM1, COM2
        DWORD test = QueryDosDevice(str.c_str(), lpTargetPath, 5000);

        // Test the return value and error if any
        if (test != 0) //QueryDosDevice returns zero if it didn't find an object
        {
            std::cout << str << ": " << lpTargetPath << std::endl;
            gotPort = true;
        }

        if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
        {
        }
    }

    return gotPort;
}

修改@Dženan答案以使用宽字符和返回整数列表

#include <string>
#include <list>

list<int> getAvailablePorts()
{
    wchar_t lpTargetPath[5000]; // buffer to store the path of the COM PORTS
    list<int> portList;

    for (int i = 0; i < 255; i++) // checking ports from COM0 to COM255
    {
        wstring str = L"COM" + to_wstring(i); // converting to COM0, COM1, COM2
        DWORD res = QueryDosDevice(str.c_str(), lpTargetPath, 5000);

        // Test the return value and error if any
        if (res != 0) //QueryDosDevice returns zero if it didn't find an object
        {
            portList.push_back(i);
            //std::cout << str << ": " << lpTargetPath << std::endl;
        }
        if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
        {
        }
    }
    return portList;
}

您可以检查windows注册表库以列出所有COM端口。这是我的代码>

我使用SerialPort.GetPortNames.SerialPorts,但它的评级太低了!有时候我不想要那种复杂的即插即用技术。。我只想插一根线,然后打字。RS232万岁@LightnessRacesinOrbit Com端口是正常的,除非您必须尝试检测何时添加了一个端口,否则它们就是地狱;
#include <string>
#include <list>

list<int> getAvailablePorts()
{
    wchar_t lpTargetPath[5000]; // buffer to store the path of the COM PORTS
    list<int> portList;

    for (int i = 0; i < 255; i++) // checking ports from COM0 to COM255
    {
        wstring str = L"COM" + to_wstring(i); // converting to COM0, COM1, COM2
        DWORD res = QueryDosDevice(str.c_str(), lpTargetPath, 5000);

        // Test the return value and error if any
        if (res != 0) //QueryDosDevice returns zero if it didn't find an object
        {
            portList.push_back(i);
            //std::cout << str << ": " << lpTargetPath << std::endl;
        }
        if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
        {
        }
    }
    return portList;
}