Hallo, weiß jemand wie man unter Windows an die installierten COM Schnittstellen auflisten kann ? Also z.B. COM1, COM2, COM4, COM16... Gruß Stefan
Ähm, ich meinte in einem Programm, hätte ich vielleicht dazu schreiben sollen, aber wir sind ja auch im Forum "PC-Programmierung"... Stefan
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
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
Stehen in der Registry unter: HKEY_LOCAL_MACHINE\Hardware\DeviceMap\SerialComm
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
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
Hi also die FTDI-Chips mit ihrem virtuellen COM-Port tauchen ganz normale in der Registry auf. Matthias
"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
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
"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.
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?
@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
> 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.
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.
> 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?
> 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.
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?
Mit SetupDiGetDeviceRegistryProperty gibt es noch nette Informationen wie z.B. den FriendlyName, den man gut im UI gebrauchen könnte.
Genauso etwas hatte ich gesucht. Werd ich morgen mal probieren! Danke für die kleine 'Nachhilfestunde' ;)
> > 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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.