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

sor*_*rin 6 c c++ windows serial-port

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

一个很好的代码示例是http://www.naughter.com/enumser.html - 其中有9种(9种!)枚举串行设备的方法.

问题是:这样做的最佳方式是什么.

要求:

  • 不打开端口以检查它们是否可用.
  • 能够检测名称不同的端口COMx.
  • 在Windows XP SP2或更高版本上工作

小智 6

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

}
Run Code Online (Sandbox Code Playgroud)

  • 这一行不做任何事情: lpTargetPath[10000]; (2认同)

Zby*_*lík 6

修改了 @D\xc5\xbeenan 答案以使用宽字符并返回整数列表

\n
#include <string>\n#include <list>\n\nlist<int> getAvailablePorts()\n{\n    wchar_t lpTargetPath[5000]; // buffer to store the path of the COM PORTS\n    list<int> portList;\n\n    for (int i = 0; i < 255; i++) // checking ports from COM0 to COM255\n    {\n        wstring str = L"COM" + to_wstring(i); // converting to COM0, COM1, COM2\n        DWORD res = QueryDosDevice(str.c_str(), lpTargetPath, 5000);\n\n        // Test the return value and error if any\n        if (res != 0) //QueryDosDevice returns zero if it didn't find an object\n        {\n            portList.push_back(i);\n            //std::cout << str << ": " << lpTargetPath << std::endl;\n        }\n        if (::GetLastError() == ERROR_INSUFFICIENT_BUFFER)\n        {\n        }\n    }\n    return portList;\n}\n
Run Code Online (Sandbox Code Playgroud)\n


Doc*_*Doc 5

如果您可以访问注册表,则该HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM密钥包含 Windows 当前支持的 COM 端口列表(在某些情况下,此信息可能已过时/不正确;例如,我怀疑,当提供串行端口的即插即用设备尚未完成检测/安装或最近已删除)。

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


Han*_*ant 3

串行端口是非常简单的设备,可以追溯到计算硬件的石器时代。它们不支持即插即用,无法判断有人插入了设备。您唯一能做的就是发现哪些端口可用,SerialPort.GetPortNames() 返回列表。一些USB模拟器可以生成一个描述性名称来配合端口名称,您可以通过WMI、Win32_SerialPort类来发现它们。

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

  • 串行端口被低估了!有时我不需要任何复杂的即插即用功能。我只想插入电缆并键入。RS232万岁! (6认同)