我正在寻找一种简单的方法来列出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部分看到它)!
你知道它为什么不起作用吗?您是否有另一种非系统特定的解决方案?
答案 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'