Forum: PC-Programmierung Com-Schnittstellen auflisten ?


von Stefan S. (phunky)


Lesenswert?

Hallo,

weiß jemand wie man unter Windows an die installierten COM
Schnittstellen auflisten kann ? Also z.B. COM1, COM2, COM4, COM16...

Gruß
Stefan

von Ralf A. (warpnine)


Lesenswert?

Im Geräte-Manager...

Ralf

von Stefan S. (phunky)


Lesenswert?

Ähm, ich meinte in einem Programm, hätte ich vielleicht dazu schreiben
sollen, aber wir sind ja auch im Forum "PC-Programmierung"...

Stefan

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

System.IO.Ports.SerialPort.GetPortNames() ist dein Freund. Und dann war
da noch http://www.catb.org/~esr/faqs/smart-questions.html#beprecise
:-)

Matthias

von Stefan S. (phunky)


Lesenswert?

Hm, Zaunpfahl...

Ich versuchs noch etwas genauer:
Ich möchte über die WIN32-API abfragen, welche serielle Schnittstellen
im System vorhanden sind (wie schon festgestellt sieht man selbige auch
im Gerätemanager).
Matthias: Dein Beispiel sieht glaube ich nach Java aus, kann ich leider
nicht.

Ok, hoffe es klappt mit dieser Beschreibung...
Stefan

von Tobi H. (tobi-) Benutzerseite


Lesenswert?

Stehen in der Registry unter:
HKEY_LOCAL_MACHINE\Hardware\DeviceMap\SerialComm

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

nö. Das ist aus der .NET 2.0 Klassenbibliothek.

Eine Möglichkeit besteht z.B. darin alle möglichen Ports mittels
CreateFile zu öffnen und das Ergebnis passend auszuwerten. Eine andere
Möglichkeit wäre z.B. in der Registry bei
HKEY_LOCAL_MACHINE\Hardware\DeviceMap\SerialComm vorbeizuschauen. Da
sind auch alle COM-Ports aufgelistet.

Matthias

von T.Stütz (Gast)


Lesenswert?

Vorsicht bei der Lösung mit "direkt" in Registry nachschauen.

Esgibt COM-Ports die sich dort nicht verewigen. Beispiel dafür
Infrarotanschluß, Bluetooth oder sonstige "virtuelle" COM-Ports.

Die erste Möglichkeit mit "CreateFile()" alle Ports kurz zu öffnen
und wieder zu schließen braucht leider etwas Zeit (256 mal bei XP).

Die dritte Möglichkeit ist in den SetupDi<XXX> Funktionen

Die vierte ist alle "symbolischen Links" herauszusuchen die
"COM<Nr>"

viel Spaß !

Gruss

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

also die FTDI-Chips mit ihrem virtuellen COM-Port tauchen ganz normale
in der Registry auf.

Matthias

von Tobi H. (tobi-) Benutzerseite


Lesenswert?

"Esgibt COM-Ports die sich dort nicht verewigen. Beispiel dafür
Infrarotanschluß, Bluetooth oder sonstige "virtuelle" COM-Ports."

Sorry, aber das ist schlichtweg falsch. Sobald diese virtuellen
Schnittstellen sich am PC anmelden erscheinen sie auch dort.

"Die erste Möglichkeit mit "CreateFile()" alle Ports kurz zu öffnen
und wieder zu schließen braucht leider etwas Zeit (256 mal bei XP)."

Das kann unerwünschte Nebeneffekte auf andere Geräte haben. Warum weiss
ich leider auch nicht, aber diese Methode blockiert/entzieht wohl
manchen Geräten die Schnittstelle

von T.Stütz (Gast)


Lesenswert?

zu "also die FTDI-Chips mit ihrem virtuellen COM-Port tauchen ganz
normale in der Registry auf."

Diese binden sich auch korrekt ein (werden Enumeriert)

zu "Sorry, aber das ist schlichtweg falsch. Sobald diese virtuellen
Schnittstellen sich am PC anmelden erscheinen sie auch dort."

Das Problem ist aber meist das diese, noch nicht sichtbaren COM-Ports
schon "belegt" sind. Bsp. du installierst ein USB-Ser (FTDI) dieser
sucht sich z.B: COM3 raus und meldet sich auch damit an. Jetzt kommt
dein Bluetooth-Gerät auch mit COM3 => wer gewinnt ?

oder onboard-Modems tragen sich nie unter "SerialDevices" ein obwohl
selbige als "COM5" ansprechbar sind.

Ich bin schon länger auf der suche nach der wirklich richtigen Methode
bin für alles offen.

Gruss

von Benedikt (Gast)


Lesenswert?

"Bsp. du installierst ein USB-Ser (FTDI) dieser
sucht sich z.B: COM3 raus und meldet sich auch damit an. Jetzt kommt
dein Bluetooth-Gerät auch mit COM3 => wer gewinnt ?"

Der erste.
Lustig wird es, wenn man zwei gleiche FTDI ICs mit gleichem EEPROM
anschließt. Dann gibt es z.B. 2x COM3, der aber nur 1x gelistet wird,
aber sich 2x öffnen lässt.

von René K. (king)


Lesenswert?

Man kann auch ohne CreateFile einfachst testen, ob ein Port existiert
oder nicht:

BOOL PortExists(UINT_PTR PortNumber)
{
    TCHAR Name[MAX_PATH];
    wsprintf(Name, TEXT("COM%u"), PortNumber);
    QueryDosDevice(Name, NULL, 0);
    return(GetLastError() == ERROR_INSUFFICIENT_BUFFER);
}

Das Durchsuchen der Registry ist jedenfalls die schlechteste Lösung,
damit könnte ich nicht mehr ruhig schlafen. Die SetupDi-Funktionen sind
doch prima, was spricht denn dagegen?

von Stefan S. (phunky)


Lesenswert?

@T.Stütz:
Habe mal eben in meine Registry geschaut, mein OnBoard-Modem steht da
als COM4 drin...

@René:
Warum ist das Extrahieren aus der Registry die schlechteste Lösung?
Nachdem was ich hier gelesen habe ist die schlechteste Lösung das
Abklappern von COM1..COMX, weil langsam und evtl. Seiteneffekte.

>Die SetupDi-Funktionen sind doch prima, was spricht denn dagegen?

Das ist deutlich mehr Aufwand als ein einfaches Abfragen der Registry
bzw. der "Abklappermethode".

Ich glaube ich werde mich für die Registrymethode entscheiden, aber
erstmal sehen was hier noch kommt...

Gruß und Danke für alle bisherigen und kommenden konstruktiven
Beiträge!

Stefan

von René K. (king)


Lesenswert?

> Warum ist das Extrahieren aus der Registry die schlechteste Lösung?

Das Registry-Layout könnte sich in der nächsten Version ändern, ohne
das Du vorher gefragt wirst. Deswegen verwende ich zum Einsammeln von
Informationen garantiert niemals direkt die Registry, wenn ich eine
gute Alternative habe. In diesem Falle kannst Du sogar noch die für
Dich am Besten geeignete Methode aussuchen.

> Nachdem was ich hier gelesen habe ist die schlechteste Lösung das
> Abklappern von COM1..COMX, weil langsam und evtl. Seiteneffekte.

Naja, so langsam ist das Abklappern nun auch wieder nicht. Jedenfalls
dann nicht, wenn Du auf CreateFile verzichtest. Und was meinst Du mit
Seiteneffekten? Sprichst Du von Benedikts kaputter Hardware?

> Das ist deutlich mehr Aufwand als ein einfaches Abfragen der
> Registry bzw. der "Abklappermethode".

Das sehe ich eigentlich nicht so, jedenfalls nicht so deutlich. Das ist
allenfalls ungewohnt, beim ersten Mal.

von Tobi H. (tobi-) Benutzerseite


Lesenswert?

Ich beziehe mich auf diesen udn folgende Beiträge
http://www.mikrocontroller.net/forum/read-8-155472.html#173707
(Nicht nur Benedikts 'kaputte' Hardware hatte damit Probleme)
Die Beiträge sind entstanden, nachdem ich genau diese abklappern
Methode für das Suchen der Schnittstellen verwendet habe

Wegen Registry: Ich hab gerad mal nachgeschaut und schon unter Win98
gabs die besagten Einträge. Aber Die SetupDi-Funktionen kannte ich
bisher garnicht. Mit welcher würde man denn die Schnittstellen finden
können?

@Rene:
Die QueryDosDevice klappt aber nur, wenn auch alle Schnittstellen sich
ordentlich einen COMx-Namen geben. Sobald eine aus diesem Namensschema
ausbricht wird sie nicht mehr gefunden.

von René K. (king)


Lesenswert?

> Die Beiträge sind entstanden, nachdem ich genau diese abklappern
> Methode für das Suchen der Schnittstellen verwendet habe

Abklappern ohne CreateFile?


> Wegen Registry: Ich hab gerad mal nachgeschaut und schon unter Win98
> gabs die besagten Einträge.

Sicherer für die Zukunft wird es dadurch aber auch nicht.


> Aber Die SetupDi-Funktionen kannte ich bisher garnicht. Mit welcher
> würde man denn die Schnittstellen finden können?

Da braucht es natürlich mehrere Funktionen, mindestens:
SetupDiGetClassDevs
SetupDiEnumDeviceInterfaces
SetupDiGetDeviceInterfaceDetail
SetupDiDestroyDeviceInfoList

Mit SetupDiGetDeviceRegistryProperty gibt es noch nette Informationen
wie z.B. den FriendlyName, den man gut im UI gebrauchen könnte.


> Die QueryDosDevice klappt aber nur, wenn auch alle Schnittstellen
> sich ordentlich einen COMx-Namen geben.

Richtig, ich wäre jetzt aber auch nicht auf die Idee gekommen, etwas
anderes haben zu wollen. Gibt es denn COM-Ports, die nicht COM heißen
aber wie COM funktionieren?

von René K. (king)


Lesenswert?

> Abklappern ohne CreateFile?

Obwohl das damit eigentlich gar nicht zusammenhängen kann. Dir wird
beim Abklappern ganz einfach irgendwo ein kleiner aber wirkungsvoller
Fehler unterlaufen sein.

von Tobi H. (tobi-) Benutzerseite


Lesenswert?

Die Frage ist, wie soll man bei abklappern mit CreateFile etwas falsch
machen? Der Code sah prinzipiell genauso aus, wie der für
QueryDosDevice, nur mit CreateFile und entsprechendem Test auf
Fehlerrückgabe. Mir ist auch schleierhaft, was da nicht ging...


Ich hab gerade mal etwas mit den SetupDi-Befehlen rumgespielt. Schlecht
ist diese Möglichkeit sicherlich nicht und für alle, die nicht selber
die Hilfe wälzen wollen hier der Code:
1
  dmsg("Start SetupDi\n");
2
    HDEVINFO devinfo = SetupDiGetClassDevs( &GUID_DEVINTERFACE_COMPORT,
3
NULL, NULL, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT );
4
    
5
  if ( devinfo == INVALID_HANDLE_VALUE )
6
  {
7
    dmsg("DevInfo failed\n");
8
    return;
9
  }
10
11
  DWORD mem_index = 0,
12
      req_size = 0;
13
  int res;
14
  SP_DEVICE_INTERFACE_DATA devinfo_data;
15
  PSP_DEVICE_INTERFACE_DETAIL_DATA pdevinfo_detail;
16
17
  ZeroMemory( &devinfo_data, sizeof( SP_DEVICE_INTERFACE_DATA ) );
18
  devinfo_data.cbSize = sizeof( SP_DEVICE_INTERFACE_DATA );
19
20
    while ( SetupDiEnumDeviceInterfaces( devinfo, NULL,
21
&GUID_DEVINTERFACE_COMPORT, mem_index, &devinfo_data ) )
22
  {
23
    dmsg("Enum Devs index=%d\n",mem_index);
24
25
    res = SetupDiGetDeviceInterfaceDetail( devinfo, &devinfo_data, NULL,
26
0, &req_size, NULL );
27
    dmsg("First call: res=%d reqsize=%d\n", res, req_size );
28
29
    pdevinfo_detail = (PSP_DEVICE_INTERFACE_DETAIL_DATA)(new char[
30
req_size + 1 ]);
31
    ZeroMemory( pdevinfo_detail, req_size+1 );
32
    pdevinfo_detail->cbSize = sizeof( SP_DEVICE_INTERFACE_DETAIL_DATA );
33
34
    res = SetupDiGetDeviceInterfaceDetail( devinfo, &devinfo_data,
35
pdevinfo_detail, req_size, NULL, NULL );
36
        
37
    dmsg("2nd call: res=%d text=\"%s\"\n", res,
38
pdevinfo_detail->DevicePath );
39
40
    delete pdevinfo_detail;
41
    ZeroMemory( &devinfo_data, sizeof( SP_DEVICE_INTERFACE_DATA ) );
42
    devinfo_data.cbSize = sizeof( SP_DEVICE_INTERFACE_DATA );
43
    mem_index++;
44
  }
45
  SetupDiDestroyDeviceInfoList( devinfo );

Die Frage, die jetzt noch bleibt, ist, wie finde ich (ohne Registry,
denn damit gehts einfach) heraus, was sich genau hinter
\\?\usb#vid_067b&pid_2303#5&3ad090d&0&1#{86e0d1e0-8089-11d
0-9ce4-08003e301f73}
verbirgt?

von René K. (king)


Lesenswert?

Mit SetupDiGetDeviceRegistryProperty gibt es noch nette Informationen
wie z.B. den FriendlyName, den man gut im UI gebrauchen könnte.

von Tobi H. (tobi-) Benutzerseite


Lesenswert?

Genauso etwas hatte ich gesucht. Werd ich morgen mal probieren! Danke
für die kleine 'Nachhilfestunde' ;)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> > Die QueryDosDevice klappt aber nur, wenn auch alle Schnittstellen
> > sich ordentlich einen COMx-Namen geben.
>
> Richtig, ich wäre jetzt aber auch nicht auf die Idee gekommen,
> etwas anderes haben zu wollen. Gibt es denn COM-Ports, die
> nicht COM heißen aber wie COM funktionieren?

Ja. ISDN-Karten der Firma Eicon ("Diva") werden mit einem Treiber
geliefert, der "virtuelle Modems" zur Verfügung stellt, die als
\\.\DiPort0 angesprochen werden können. Ein Mapping auf COM-Namen
ist zwar auch möglich, aber nicht zwingend.
Verwendet man diese speziellen Namen, kann man sich wenigstens sicher
sein, nicht doch versehentlich mit falscher Hardware zu kommunizieren.
Nein, für das "gelbe vom Ei" halte ich diese Idee auch nicht.

von Tobi H. (tobi-) Benutzerseite


Lesenswert?

Nächstes Problem: SetupDiGetDeviceRegistryProperty liefert zwar eine
Menge Infos aber leider nichts der Art COMx. Der User Friendly Name ist
z.b 'Kommunikationsanschluss (COM1)'
Die benötigte Eigenschaft (PortName heißts in der Reg) ist nicht damit
zugreifbar. Schade, sonst wäre das wirklich praktisch gewesen :/

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.