使用Python列出可用的com端口

时间:2012-08-23 11:25:31

标签: python pyserial

我正在寻找一种简单的方法来列出PC上所有可用的com端口。

我找到了这种方法,但它是特定于Windows的:Listing serial (COM) ports on Windows?

我在Windows 7 PC上使用Python 3和pySerial。

我在pySerial API(http://pyserial.sourceforge.net/pyserial_api.html)中找到了一个列出com端口的函数serial.tools.list_ports.comports()(正是我想要的)。

import serial.tools.list_ports
print(list(serial.tools.list_ports.comports()))

但它似乎不起作用。当我的USB到COM网关连接到PC时(我在设备管理器中看到COM5),此COM端口不包含在list_ports.comports()返回的列表中。相反,我只得到似乎连接到调制解调器的COM4(我没有在设备管理器的COM& LPT部分看到它)!

你知道它为什么不起作用吗?您是否有另一种非系统特定的解决方案?

12 个答案:

答案 0 :(得分:129)

这是我使用的代码。

使用Python 2和Python 3在Windows 8.1 x64,Windows 10 x64,Mac OS X 10.9.x / 10.10.x / 10.11.x和Ubuntu 14.04 / 14.10 / 15.04 / 15.10上成功测试。

import sys
import glob
import serial


def serial_ports():
    """ Lists serial port names

        :raises EnvironmentError:
            On unsupported or unknown platforms
        :returns:
            A list of the serial ports available on the system
    """
    if sys.platform.startswith('win'):
        ports = ['COM%s' % (i + 1) for i in range(256)]
    elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
        # this excludes your current terminal "/dev/tty"
        ports = glob.glob('/dev/tty[A-Za-z]*')
    elif sys.platform.startswith('darwin'):
        ports = glob.glob('/dev/tty.*')
    else:
        raise EnvironmentError('Unsupported platform')

    result = []
    for port in ports:
        try:
            s = serial.Serial(port)
            s.close()
            result.append(port)
        except (OSError, serial.SerialException):
            pass
    return result


if __name__ == '__main__':
    print(serial_ports())

答案 1 :(得分:23)

您可以使用:

python -c "import serial.tools.list_ports;print serial.tools.list_ports.comports()"

按知道端口过滤: python -c "import serial.tools.list_ports;print [port for port in serial.tools.list_ports.comports() if port[2] != 'n/a']"

在此处查看更多信息: https://pyserial.readthedocs.org/en/latest/tools.html#module-serial.tools.list_ports

答案 2 :(得分:11)

对托马斯的出色答案的一个可能的改进是让Linux和OSX也尝试打开端口并只返回那些可以打开的端口。这是因为Linux至少列出了一大堆端口作为/ dev /中的文件,这些文件没有连接到任何东西。如果您正在终端中运行,/ dev / tty是您正在工作并打开和关闭的终端,它可能会破坏您的命令行,因此glob的目的不是这样做。代码:

    # ... Windows code unchanged ...

    elif sys.platform.startswith ('linux'):
        temp_list = glob.glob ('/dev/tty[A-Za-z]*')

    result = []
    for a_port in temp_list:

        try:
            s = serial.Serial(a_port)
            s.close()
            result.append(a_port)
        except serial.SerialException:
            pass

    return result

对Thomas代码的修改仅在Ubuntu 14.04上进行了测试。

答案 3 :(得分:5)

moylop260的回答进行了改进:

import serial.tools.list_ports
comlist = serial.tools.list_ports.comports()
connected = []
for element in comlist:
    connected.append(element.device)
print("Connected COM ports: " + str(connected))

列出硬件中存在的端口,包括正在使用的端口。根据{{​​3}}

,列表中存在更多信息

答案 4 :(得分:4)

在pyserial文档中基本提到了这一点 https://pyserial.readthedocs.io/en/latest/tools.html#module-serial.tools.list_ports

         gcloud alpha cloud-shell ssh

结果:

COM1:通信端口(COM1)[ACPI \ PNP0501 \ 1]

COM7:MediaTek USB端口(COM7)[USB VID:PID = 0E8D:0003 SER = 6 LOCATION = 1-2.1]

答案 5 :(得分:4)

可能会迟到,但可能会帮助有需要的人。

import serial.tools.list_ports


class COMPorts:

    def __init__(self, data: list):
        self.data = data

    @classmethod
    def get_com_ports(cls):
        data = []
        ports = list(serial.tools.list_ports.comports())

        for port_ in ports:
            obj = Object(data=dict({"device": port_.device, "description": port_.description.split("(")[0].strip()}))
            data.append(obj)

        return cls(data=data)

    @staticmethod
    def get_description_by_device(device: str):
        for port_ in COMPorts.get_com_ports().data:
            if port_.device == device:
                return port_.description

    @staticmethod
    def get_device_by_description(description: str):
        for port_ in COMPorts.get_com_ports().data:
            if port_.description == description:
                return port_.device


class Object:
    def __init__(self, data: dict):
        self.data = data
        self.device = data.get("device")
        self.description = data.get("description")


if __name__ == "__main__":
    for port in COMPorts.get_com_ports().data:
        print(port.device)
        print(port.description)

    print(COMPorts.get_device_by_description(description="Arduino Leonardo"))
    print(COMPorts.get_description_by_device(device="COM3"))

答案 6 :(得分:1)

有几种选择:

使用NULL lpDeviceName调用QueryDosDevice以列出所有DOS设备。然后依次使用CreateFile和GetCommConfig与每个设备名称来确定它是否是串行端口。

使用GUID_DEVINTERFACE_COMPORT的ClassGuid调用SetupDiGetClassDevs

WMI is also available to C/C++ programs

win32 newsgroup和CodeProject上有一些对话,呃,project

答案 7 :(得分:1)

带有pySerial软件包的一线解决方案。

python -m serial.tools.list_ports

答案 8 :(得分:0)

请尝试以下代码:

import serial
ports = serial.tools.list_ports.comports(include_links=False)
for port in ports :
    print(port.device)

首先,您需要导入软件包以进行串行端口通信, 所以:

import serial

然后创建当前可用的所有串行端口的列表:

ports = serial.tools.list_ports.comports(include_links=False)

然后遍历整个列表,例如,您可以打印端口名称:

for port in ports :
    print(port.device)

这只是一个如何获取端口列表并打印其名称的示例,但是您可以使用此数据进行其他一些选择。只需在

之后打印不同的变体
  

端口。

答案 9 :(得分:0)

尝试此代码

import serial.tools.list_ports
for i in serial.tools.list_ports.comports():
    print(i) 

它返回

COM1 - Port de communication (COM1)
COM5 - USB-SERIAL CH340 (COM5)

如果您只是不使用示例COM1的端口名称

import serial.tools.list_ports
for i in serial.tools.list_ports.comports():
    print(str(i).split(" ")[0])

它返回

COM1
COM5

就我而言 py 3.7 64bits

答案 10 :(得分:0)

仅适用于Windows:

import winreg
import itertools

def serial_ports() -> list:
    path = 'HARDWARE\\DEVICEMAP\\SERIALCOMM'
    key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path)

    ports = []
    for i in itertools.count():
        try:
            ports.append(winreg.EnumValue(key, i)[1])
        except EnvironmentError:
            break

    return ports

if __name__ == "__main__":
    ports = serial_ports()

答案 11 :(得分:0)

一些简单的东西,但我经常使用它。

import serial.tools.list_ports as ports

com_ports = list(ports.comports()) # create a list of com ['COM1','COM2'] 
    for i in com_ports:            
        print(i.device) # returns 'COMx'