Serielle (COM) Ports unter Windows auflisten?

Lesezeit: 4 Minuten

Benutzer-Avatar
Eli Bendersky

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:

  1. 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.

  2. 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:

  1. 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.

  2. Anruf SetupDiGetClassDevs mit einer ClassGuid von GUID_DEVINTERFACE_COMPORT.

  3. WMI ist auch für C/C++-Programme verfügbar.

Es gibt einige Gespräche auf der Win32-Newsgroup und ein CodeProject, äh, Projekt.

  • 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.

    – Craig McQueen

    2. Juli 2012 um 3:20 Uhr

Benutzer-Avatar
zdav

Das PySerial-Projekt bietet a Paar Lösungen.

  • 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!

http://eli.thegreenplace.net/2009/07/31/listing-all-serial-ports-on-windows-with-python/

Besonders dieses Beispiel:

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

Benutzer-Avatar
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

Benutzer-Avatar
Ben

In der pyserial-Distribution gibt es jetzt ein Beispiel namens scanwin32.py, das dies tut

http://pyserial.sourcearchive.com/documentation/2.5/scanwin32_8py_source.html

1383290cookie-checkSerielle (COM) Ports unter Windows auflisten?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy