Frage

Ich bin auf der Suche nach einem robusten Weg, um die verfügbaren seriellen Ports (COM) auf einem Windows-Rechner aufzulisten. Es gibt diesen Beitrag zu WMI , aber ich würde etwas weniger .NET spezifische mag - ich mag die Liste der Ports in einem Python oder C ++ Programm erhalten, ohne .NET

.

Ich weiß noch zwei weitere Ansätze:

  1. , um die Information in dem HARDWARE\\DEVICEMAP\\SERIALCOMM Registrierungsschlüssel lesen. Dies sieht aus wie eine gute Option, aber ist es robust ? Ich kann keine Garantie online oder in MSDN feststellen, dass diese Registry-Zelle in der Tat immer die vollständige Liste der verfügbaren Ports hält.

  2. Tryint CreateFile auf COMN mit N eine Zahl von 1 bis etwas zu nennen. Das ist nicht gut genug, da einige COM-Ports COMN nicht genannt. Zum Beispiel erstellt einig virtueller COM-Ports CSNA0, CSNB0 genannt, und so weiter, so würde ich nicht auf dieser Methode verlassen.

Jede andere Methoden / Ideen / Erfahrungen zu teilen?

Edit: durch die Art und Weise, hier ist eine einfache Python-Implementierung des Portnamen aus der Registry zu lesen:

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
War es hilfreich?

Lösung

Mehrere Optionen stehen zur Verfügung:

  1. Rufen Sie QueryDosDevice mit einem NULL lpDeviceName alle DOS-Geräte aufzulisten. Dann verwenden Sie Create und GetCommConfig mit jedem Gerätenamen in drehen, um herauszufinden, ob es eine serielle Schnittstelle.

  2. Rufen Sie SetupDiGetClassDevs mit einem ClassGUID von GUID_DEVINTERFACE_COMPORT.

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

Es gibt einige Gespräche auf der win32 Newsgroup und ein Codeproject, äh, Projekt .

Andere Tipps

Mit pyserial mit Python:

import serial.tools.list_ports


ports = list(serial.tools.list_ports.comports())
for p in ports:
    print p

Das pyserial Projekt bietet eine paar Lösungen .

Ich habe gerade die folgenden, basierend auf das Lesen durch die C ++ Quelle EnumSerialPorts und zu sehen, die Funktion GetDefaultCommConfig(). Es sah aus wie die einfachste Methode, mit einfachen ANSI C und einen einzigen API-Aufruf für jeden möglich 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;
}

Dies ist auf jeden Fall ziemlich spät, aber es erwies sich als hilfreich für mich!

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

Es gibt ein Beispiel in der pyserial Distro jetzt, tut dies genannt scanwin32.py

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

Ich denke, WMI ist der Weg zu gehen, da es ziemlich einfach ist, in Gang zu bringen, und es hat nur minimalen Code. Es erspart Ihnen, in der Registry zu graben und gibt Ihnen eine Garantie, dass es für allgemeinere Situationen in der Zukunft funktionieren wird.

Sie können alles installieren mit pip install pypiwin32 WMI benötigt und es funktioniert out-of-the-box.

Code

import wmi

query = "SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%(COM%)'"
coms  = wmi.WMI().query(query)

for com in coms:
    print(com.Name)

Output

Communications Port (COM1)
mbed Serial Port (COM3)
mbed Serial Port (COM5)

Meine Vermutung ist, dass der Port eine Art Plug ‚n Play so sollte das hervorragend funktionieren. Aus irgendeinem Grund Win32_SerialPort nicht für alle Ports arbeiten.

Heute gibt es eine Powershell Einzeiler dafür.

[System.IO.Ports.SerialPort]::GetPortNames()
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top