Ich suche nach einer robusten Möglichkeit, die verfügbaren seriellen (COM) Ports auf einem Windows-Computer aufzulisten. Es gibt diesen Beitrag über die Verwendung von WMI, aber ich hätte gerne etwas weniger .NET-spezifisches – ich möchte die Liste der Ports in einem Python- oder C++-Programm ohne .NET abrufen.
Ich kenne derzeit zwei weitere Ansätze:
Lesen Sie die Informationen in der HARDWARE\\DEVICEMAP\\SERIALCOMM Registrierungsschlüssel. Das sieht nach einer großartigen Option aus, ist es aber robust? Ich kann online oder in MSDN keine Garantie dafür finden, dass diese Registrierungszelle tatsächlich immer die vollständige Liste der verfügbaren Ports enthält.
Versuche anzurufen CreateFile an COMN mit N eine Zahl von 1 bis etwas. Dies ist nicht gut genug, da einige COM-Ports nicht COMN heißen. Beispielsweise heißen einige erstellte virtuelle COM-Ports CSNA0, CSNB0 usw., daher würde ich mich nicht auf diese Methode verlassen.
Irgendwelche anderen Methoden/Ideen/Erfahrungen zum Teilen?
Bearbeiten: Übrigens, hier ist eine einfache Python-Implementierung zum Lesen der Portnamen aus der Registrierung:
import _winreg as winreg
import itertools
def enumerate_serial_ports():
""" Uses the Win32 registry to return a iterator of serial
(COM) ports existing on this computer.
"""
path="HARDWARE\\DEVICEMAP\\SERIALCOMM"
try:
key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path)
except WindowsError:
raise IterationError
for i in itertools.count():
try:
val = winreg.EnumValue(key, i)
yield (str(val[1]), str(val[0]))
except EnvironmentError:
break
Sieht sehr nützlich aus, um COM-Ports zu finden – ich werde versuchen, es zu verwenden, um den Arduino-Port zu finden
– SimpleSi
18. Januar 2013 um 20:52 Uhr
Verwendung von pySerial mit Python:
import serial.tools.list_ports
ports = list(serial.tools.list_ports.comports())
for p in ports:
print p
Oder direkt von der Kommandozeile, python -m serial.tools.list_ports
– Jetblau
24. August 2017 um 0:13 Uhr
Achten Sie darauf, das p in Klammern zu setzen
– Eric Hedengren
15. Juni 2021 um 20:42 Uhr
Es stehen mehrere Optionen zur Verfügung:
Anruf QueryDosDevice mit einem NULL lpDeviceName, um alle DOS-Geräte aufzulisten. Verwenden Sie dann CreateFile und GetCommConfig mit jedem Gerätenamen der Reihe nach, um herauszufinden, ob es sich um eine serielle Schnittstelle handelt.
Anruf SetupDiGetClassDevs mit einer ClassGuid von GUID_DEVINTERFACE_COMPORT.
Der Versuch, QueryDosDevice zu verwenden, hat aber Probleme zu wissen, welche Geräte serielle Ports sind. GetCommConfig ist aus irgendeinem Grund nicht Teil von Pywin32
– Eli Bendersky
30. Juli 2009 um 10:56 Uhr
Ich war beeindruckt, wie gut Teraterm listet serielle Ports auf. Ich habe in den Quellcode geschaut und es stellt sich heraus, ListupSerialPort() in ttcmn.c bezieht sich auf dieses CodeProject-Projekt.
Dies ist eine relativ neue Funktion für Pyserial, sollte aber in Zukunft die richtige Lösung sein.
– Theorie
14. Februar 2017 um 17:20 Uhr
Ich habe gerade Folgendes erstellt, basierend auf dem Lesen der C++-Quelle zu EnumSerialPorts und sehen die Funktion GetDefaultCommConfig(). Es sah aus wie die einfachste Methode mit einfachem ANSI C und einem einzigen API-Aufruf für jeden möglichen COM-Port.
#include <stdio.h>
#include <windows.h>
#include <winbase.h>
BOOL COM_exists( int port)
{
char buffer[7];
COMMCONFIG CommConfig;
DWORD size;
if (! (1 <= port && port <= 255))
{
return FALSE;
}
snprintf( buffer, sizeof buffer, "COM%d", port);
size = sizeof CommConfig;
// COM port exists if GetDefaultCommConfig returns TRUE
// or changes <size> to indicate COMMCONFIG buffer too small.
return (GetDefaultCommConfig( buffer, &CommConfig, &size)
|| size > sizeof CommConfig);
}
int main()
{
int i;
for (i = 1; i < 256; ++i)
{
if (COM_exists( i))
{
printf( "COM%d exists\n", i);
}
}
return 0;
}
Das ist definitiv ziemlich spät, aber es hat sich als hilfreich für mich erwiesen!
import re
def full_port_name(portname):
""" Given a port-name (of the form COM7,
COM12, CNCA0, etc.) returns a full
name suitable for opening with the
Serial class.
"""
m = re.match('^COM(\d+)$', portname)
if m and int(m.group(1)) < 10:
return portname
return '\\\\.\\' + portname
Keine Sorge, es war lustig zu sehen 🙂
– Eli Bendersky
6. Juni 2013 um 20:58 Uhr
Paul Williams
Heutzutage gibt es dafür einen Powershell-Einzeiler.
[System.IO.Ports.SerialPort]::GetPortNames()
Keine Sorge, es war lustig zu sehen 🙂
– Eli Bendersky
6. Juni 2013 um 20:58 Uhr
Ben
In der pyserial-Distribution gibt es jetzt ein Beispiel namens scanwin32.py, das dies tut
Sieht sehr nützlich aus, um COM-Ports zu finden – ich werde versuchen, es zu verwenden, um den Arduino-Port zu finden
– SimpleSi
18. Januar 2013 um 20:52 Uhr