webentwicklung-frage-antwort-db.com.de

Wie erhalte ich eine Liste der verfügbaren seriellen Schnittstellen in Win32?

Ich habe einen älteren Code, der eine Liste der verfügbaren COM-Anschlüsse auf dem PC enthält, indem ich die Funktion EnumPorts() aufrufe und dann nach den Anschlussnamen filtere, die mit "COM" beginnen.

Zu Testzwecken wäre es sehr nützlich, wenn ich diesen Code mit etwas wie com0com verwenden könnte, das Paare von virtuellen COM-Ports bereitstellt, die als Nullmodem in einer Schleife miteinander verbunden sind.

Die com0com-Ports werden jedoch von der Funktion EnumPorts() nicht gefunden (auch ohne Filterung nach "COM"). HyperTerminal und SysInternals PortMon können beide sehen, daher bin ich sicher, dass es korrekt installiert ist.

Gibt es also eine andere Win32-Funktion, die eine definitive Liste der verfügbaren seriellen Schnittstellen liefert?

49
GrahamS

Das von Nick D vorgeschlagene EnumSerialPorts v1.2 verwendet neun verschiedene Methoden, um die seriellen Ports aufzulisten! Wir haben mit Sicherheit keine geringe Auswahl, obwohl die Ergebnisse sehr unterschiedlich zu sein scheinen.

Um anderen die Mühe zu ersparen, liste ich sie hier auf und zeige ihren Erfolg bei der Suche nach dem com0com Ports auf meinem PC (XP Pro SP2):

  1. CreateFile ("COM" + 1-> 255) wie von Wael Dalloul vorgeschlagen
    ✔ Gefundene com0com-Ports, dauerte 234 ms.

  2. QueryDosDevice ()
    ✔ Gefundene com0com Ports, dauerte 0ms.

  3. GetDefaultCommConfig ("COM" + 1-> 255)
    ✔ Gefundene com0com-Ports, dauerte 235 ms.

  4. "SetupAPI1" mit Aufrufen von SETUPAPI.DLL
    ✔ Gefundene com0com-Ports, von denen auch "Anzeigenamen" gemeldet wurden, benötigten 15 ms.

  5. "SetupAPI2" mit Aufrufen von SETUPAPI.DLL
    ✘ com0com-Ports wurden nicht gefunden, "Anzeigenamen" wurden gemeldet, es dauerte 32 ms.

  6. EnumPorts ()
    ✘ Einige Nicht-COM-Ports wurden gemeldet, com0com-Ports wurden nicht gefunden, es dauerte 15 ms.

  7. Verwenden von WMI-Aufrufen
    ✔ Gefundene com0com-Ports, von denen auch "Anzeigenamen" gemeldet wurden, dauerten 47 ms.

  8. COM-Datenbank, die Aufrufe von MSPORTS.DLL verwendet
    ✔/✘ Einige Nicht-COM-Ports wurden gemeldet, com0com-Ports wurden gefunden, es dauerte 16 ms.

  9. Über den Registrierungsschlüssel HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM iterieren
    ✔ Gefundene com0com Ports, dauerte 0ms. Dies ist anscheinend das, was SysInternals PortMon verwendet.

Basierend auf diesen Ergebnissen denke ich, dass die WMI-Methode meinen Anforderungen am besten entspricht, da sie relativ schnell ist und als Bonus auch die Anzeigenamen enthält (z. B. "Communications Port (COM1)", "com0com - Serial Port Emulator").

76
GrahamS

Es scheint, dass es keine einfache Aufgabe ist.

Überprüfen Sie Folgendes: EnumSerialPorts v1.2

11

sie können beispielsweise eine Schleife von 1 bis 50 erstellen und versuchen, jeden Port zu öffnen. Wenn der Port verfügbar ist, funktioniert das Öffnen. Wenn der Port verwendet wird, wird ein Freigabefehler angezeigt. Wenn der Port nicht installiert ist, wird der Fehler "Datei nicht gefunden" angezeigt.

um den Port zu öffnen, benutze CreateFile API:

HANDLE Port = CreateFile(
                  "\\\\.\\COM1",
                  GENERIC_READ | GENERIC_WRITE,
                  0,
                  NULL,
                  OPEN_EXISTING,
                  FILE_ATTRIBUTE_NORMAL,
                  NULL);

dann überprüfen Sie das Ergebnis.

5
Wael Dalloul

Ich habe PJ Naughter 's EnumSerialPorts als portablere und individuellere Formulare reorganisiert, das ist nützlicher.

Aus Gründen der Kompatibilität verwende ich C anstelle von C++.

Wenn Sie es brauchen oder daran interessiert sind, besuchen Sie bitte den Beitrag in meinem Blogger.

1
Gaiger Chen

In meinem Fall benötige ich sowohl die vollständigen Namen als auch die COM-Port-Adressen. Ich habe physische serielle Schnittstellen, serielle USB-Schnittstellen und virtuelle serielle com0com-Schnittstellen.

Wie die akzeptierte Antwort vermuten lässt, verwende ich WMI-Aufrufe. SELECT * FROM Win32_PnPEntity Findet alle Geräte. Es gibt physische Geräte wie dieses zurück und die Adresse kann aus Caption analysiert werden:

Serial Port for Barcode Scanner (COM13)

Für com0com-Ports ist Caption jedoch wie folgt (keine Adresse):

com0com - serial port emulator

SELECT * FROM Win32_SerialPort Gibt Adressen (DeviceID) sowie vollständige Namen (Name) zurück. Es werden jedoch nur physische serielle Ports und com0com-Ports gefunden, keine seriellen USB-Ports.

Letztendlich benötige ich also zwei WMI-Aufrufe: SELECT * FROM Win32_SerialPort (Adresse ist DeviceID) und SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%(COM%' (Adresse kann aus Caption analysiert werden). Ich habe den Win32_PnPEntity - Aufruf eingegrenzt, da nur Geräte gefunden werden müssen, die beim ersten Aufruf nicht gefunden wurden.

1
Ville-Valtteri