Hallo, wieder mal einen Frage von mir, die wahrscheinlich recht einfach ist : Wenn ich unter C mit 'EnumPorts' alle Ports listen lasse und dann nach COM* suche, finde ich immer die Ports Com1 bis Com4. Die Systemsteuerung zeigt aber z.B. nur die Ports Com1 und 2. Warum ist das so ?
Bei mir ist das nicht so. Du solltest vielleicht mal den konkreten Quelltext veröffentlichen.
O.K. ....... int checkCOMPort(char *COMPort) { int i, numPrt, needed; int retVal = 0; PORT_INFO_2 *pi = NULL; char *z = NULL; int posDP = -1; // Get required memory size EnumPorts( NULL, // name of port object 2, // general port info (LPBYTE) z, // port information buffer 0, // size of port information buffer (LPDWORD) &needed, // bytes required (LPDWORD) &numPrt // number of port enumerated ); // Allocate memory z = malloc (needed); memset (z, 0, needed); // Enumerate ports if (!EnumPorts ( NULL, // name of port object 2, // general port info (LPBYTE) z, // port information buffer needed, // size of port information buffer (LPDWORD) &needed, // bytes required (LPDWORD) &numPrt // number of port enumerated )) { if (z) free (z); if (pi) free (pi); return 0; } // Allocate structured memory pi = calloc (numPrt, sizeof (PORT_INFO_2)); memcpy (pi, z, numPrt * sizeof (PORT_INFO_2)); for (i = 0; i < numPrt; i++) { if ( pi[i].pPortName != NULL ) { if (strstr(pi[i].pPortName, COMPort)) { // get Com Port number posDP = strstr(pi[i].pPortName, ":"); retVal = atol(posDP-1); break; } } } if (z) free (z); if (pi) free (pi); return retVal; }
:
Bearbeitet durch User
Ich checke jetzt mit 'CreateFile' alle ComPorts, die mit 'EnumPorts' hochkommen. Damit lassen sich nur die unbelegten und vorhandenen Ports öffnen. Dann habe ich was ich will ...
The EnumPorts function enumerates the ports that are available for printing on a specified server ...
heute mal ohne schrieb: > The EnumPorts function enumerates the ports that are available for > printing on a specified server ... ja .......
Ich denke, du verwendest da die falsche Funktion. Offensichtlich ist sie für die Abfrage vom Drucker-Ports vorgesehen. Hier wurde das Thema schon diskutiert: http://stackoverflow.com/questions/1388871/how-do-i-get-a-list-of-available-serial-ports-in-win32 Jetzt bin ich aber selbst überrascht, wie kompliziert das Thema ist, denn bei mir hatte es vor ca 20 jahren "einfach so" beim ersten Anlauf funktioniert. Allerdings hatte ich eine andere Windows API Funktion verwendet, irgendwas, was es schon zu Windows NT Zeiten gab. Schade, dass ich den Quelltext nicht mehr habe.
Lutz G. schrieb: > Warum ist das so ? Weil Windows seit Beginn ein schlecht programmiertes Betriebssystem ist. Das hat sich bis heute leider nur minimal gebessert, nur an der Grafik wird immer viel gebastelt. Lutz G. schrieb: > Ich checke jetzt mit 'CreateFile' alle ComPorts, > die mit 'EnumPorts' hochkommen. Damit lassen sich > nur die unbelegten und vorhandenen Ports öffnen. Das hört sich eher nach einer Bastellösung, statt einer vernünftigen Prüfung an.
Die Frage scheint nicht richtig zu sein, "Warum sind Com1..4: immer da ?" sind sie es denn? nein, je nach Rechner kann das Bios diese schon zeigen, oder der virtuelle Com Treiber per USB. Ich habe nun festgestellt das der oben genannte Weg der richtige ist, alle angefangen von Com1 öffnen wenn das klappt ist es schon mal die "halbe Miete" das heisst aber nicht das auch jeder bereit ist. Ich hatte mir mal ein Fernsteuerprogramm für mein Antennenmessgerät geschrieben und da kam ich mit einer festen Com Nummer nicht weiter weil jeder USB zu RS232 Adapter seine ID und Comzugehörigkeit ablegt und kommt der nächste Adapter dazu wird aus dem Pool nach USB ID entschieden und wenn eine ComN schon vergeben war die nächste Com Nummer vergeben, also immer alle Com durchprüfen bis die sinnvolle erwartete Antwort kommt.
Der nachfolgende Code enumeriert alle Com Ports von 0 bis 30 und erkennt ob sie sich öffnen lassen.
1 | CString longName, shortName; |
2 | |
3 | for (int i= 0; i< 30; i++) |
4 | {
|
5 | longName.Format(_T("\\\\.\\COM%d"),i); |
6 | HANDLE hPort = CreateFile( longName, |
7 | GENERIC_READ | GENERIC_WRITE, |
8 | 0, |
9 | 0, |
10 | OPEN_EXISTING, |
11 | 0, |
12 | NULL
|
13 | );
|
14 | if ( hPort != INVALID_HANDLE_VALUE ) |
15 | {
|
16 | // Port lässt sich öffnen
|
17 | shortName.Format(_T("COM%d"),i); |
18 | CloseHandle(hPort); |
19 | }
|
20 | }
|
:
Bearbeitet durch User
Hallo, eine wesentlich schnellere Variante ist übrigens, statt den Port zum schreiben zu öffnen mit GetDefaultCommConfig zu arbeiten. https://msdn.microsoft.com/de-de/library/windows/desktop/aa363262(v=vs.85).aspx das geht wesentlich schneller und man kann es dann einfach über alle 256 möglichen Ports machen.
nicht"Gast" schrieb: > das geht wesentlich schneller und man kann es dann einfach über alle 256 > möglichen Ports machen. dumm nur das die ports nicht alle mit COM im namen anfangen müssen. Hier gab es doch schon fertige Lösungen: http://stackoverflow.com/questions/1388871/how-do-i-get-a-list-of-available-serial-ports-in-win32 entweder die Registry direkt auslesen oder mit WMI arbeiten.
Hans-Georg L. schrieb: > Der nachfolgende Code enumeriert alle Com Ports von 0 bis 30 und erkennt > ob sie sich öffnen lassen. > Wenn man i von 1 bis 256 durchlaufen lässt, kann man damit alle noch freien Comports ermitteln.
1 | CString longName, shortName; |
2 | |
3 | for (int i= 1; i<= 256; i++) |
4 | {
|
5 | longName.Format(_T("\\\\.\\COM%d"),i); |
6 | HANDLE hPort = CreateFile( longName, |
7 | GENERIC_READ | GENERIC_WRITE, |
8 | 0, |
9 | 0, |
10 | OPEN_EXISTING, |
11 | 0, |
12 | NULL
|
13 | );
|
14 | if ( hPort != INVALID_HANDLE_VALUE ) |
15 | {
|
16 | // Port lässt sich öffnen
|
17 | shortName.Format(_T("COM%d"),i); |
18 | CloseHandle(hPort); |
19 | }
|
20 | }
|
Peter II schrieb: > dumm nur das die ports nicht alle mit COM im namen anfangen müssen. Kannst du dich bitte mal erklären? Bisher hatte ich unter Windows noch keine serielle Schnittstelle, die nicht COMx war. PS: Der Link ist trozdem gut. Die Klasse zum enumerieren ist nicht schlecht.
T.roll schrieb: > Lutz G. schrieb: >> Warum ist das so ? > > Weil Windows seit Beginn ein schlecht programmiertes Betriebssystem ist. > Das hat sich bis heute leider nur minimal gebessert, nur an der Grafik > wird immer viel gebastelt. > > Lutz G. schrieb: >> Ich checke jetzt mit 'CreateFile' alle ComPorts, >> die mit 'EnumPorts' hochkommen. Damit lassen sich >> nur die unbelegten und vorhandenen Ports öffnen. > > Das hört sich eher nach einer Bastellösung, statt einer vernünftigen > Prüfung an. Unter Linux ist es noch viel verkrampfter die real existierenden tty Geräte aufzulisten. Die Methode mit dem probeweise CreateFile aller Kandidaten ist unter Windows die empfohlene und einzig zuverlässige Lösung. Man merkt daß Du Dich noch nie mit diesem Thema beschäftigt hast aber einfach mal Deinen Senf dazu abgeben musst, typisch Troll halt eben.
nicht"Gast" schrieb: > Kannst du dich bitte mal erklären? Bisher hatte ich unter Windows noch > keine serielle Schnittstelle, die nicht COMx war. com2com gibt es z.b. (ok fängt mit com an, würde aber nicht gefunden werden)
Bernd K. schrieb: > Unter Linux ist es noch viel verkrampfter die real existierenden tty > Geräte aufzulisten. nicht wirklich, man befragt dafür einfach udev.
Der E. schrieb: > Hans-Georg L. schrieb: >> Der nachfolgende Code enumeriert alle Com Ports von 0 bis 30 und erkennt >> ob sie sich öffnen lassen. >> > Wenn man i von 1 bis 256 durchlaufen lässt, kann man damit alle noch > freien Comports ermitteln. > Soviel Intelligenz habe ich dem TO schon zugetraut das er 30 durch ein andere Zahl ersetzen kann kopfschüttel Was verstehst du unter "freien" Com ports ? Wenn du einen USB RS232 Wandler einsteckst bekommt der eine Port Nummer und diese Nummer ist nicht mehr frei auch wenn er abgesteckt wird, kann aber nicht geöffnet werden.
Schonmal im die inaktiven geräte anzeigen lassen? ich wette da ist auf com3 und 4 ein treiber installiert nur nicht aktiv.
Peter II schrieb: > com2com gibt es z.b. (ok fängt mit com an, würde aber nicht gefunden > werden) Du hast deinen eigenen Link nicht durchgelesen oder? sowohl CreateFile als auch GetDefaultCommConfig finden diese Ports. Kleiner Tip am Rande. Das Programm zum erzeugen der Brücke heißt com0com. Das heißt noch lange nicht, das die Ports so heißen. Es legt zwei virtuelle com ports an. Auf meinem Rechner hier heißen die com20 und com21. Wenn man die Registry Einträge ausliest kann man an diese zusätzlichen Informationen heran kommen. Dann kann man, so man möchte, Zusatzinformationen anzeigen (wie com0com oder VCP0 u.s.w.). Grüße
nicht"Gast" schrieb: > Du hast deinen eigenen Link nicht durchgelesen oder? sowohl CreateFile > als auch GetDefaultCommConfig finden diese Ports. CreateFile und GetDefaultCommConfig finden keinen Port. Sie öffnen den Port den man übergibt und geben eine Rückmeldung.
1 | for (int i= 1; i<= 256; i++) |
2 | {
|
3 | longName.Format(_T("\\\\.\\COM%d"),i); |
Damit muss man wissen wie der Name vom port aufgebaut ist. > Kleiner Tip am Rande. Das Programm zum erzeugen der Brücke heißt > com0com. Das heißt noch lange nicht, das die Ports so heißen. Es legt > zwei virtuelle com ports an. Auf meinem Rechner hier heißen die com20 > und com21. konnte man damit nicht auch ports mit freien Namen anlegen? Sie mussten meines wissens nicht mit COM anfangen.
Hans-Georg L. schrieb: > alle Com Ports von 0 bis 30 Hans-Georg L. schrieb: >
1 | for (int i= 0; i< 30; i++) |
Dann meinst Du wohl:
1 | for (int i= 0; i<=30; i++) |
Chregu
http://www.naughter.com/enumser.html "Internally the code provides 9 different ways (yes you read that right: Nine) of enumerating serial ports: Using CreateFile, QueryDosDevice, GetDefaultCommConfig, two ways using the Setup API, EnumPorts, WMI, Com Database & enumerating the values under the registry key HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM." ...das findet quasi alles ;D
O.K. So wie es aussieht führen viele Wege nach 'COM' :-) Vielen Dank für die schnelle Hilfe. Ich werde mich mal durch die Links arbeiten :-) Ich habe es jetzt erst mal mit EnumPorts(), dann filtern nach "COM" und anschließendem CreateFile() und Antwort prüfen gelößt. So funktioniert es auf 3 PC's ... Damit wird jetzt getestet ob der Bediener an einem Prüfgerät eine USB Port ( der dann einen COM erzeugt ) gesteckt hat. Dann kann der Test weiter laufen. Das gleiche beim Abstecken. Vorher wurde der Test über einen Bedienereingabe fortgesetzt und der Zeitpunkt einer Bedienereingabe ist seeehhhr variabel ! Vielen Dank :-) Gruß Lutz
Peter II schrieb: > konnte man damit nicht auch ports mit freien Namen anlegen? Man kann unter Windows ja nicht mal einen File auf irgendetwas im Bereich Com1 .. Com9 umbenennen (oder sollte das das BIOS noch reinpfuschen?).
W.A. schrieb: > Man kann unter Windows ja nicht mal einen File auf irgendetwas im > Bereich Com1 .. Com9 umbenennen ?? Was wolltest Du machen? Zum Beispiel eine Datei "Horst.txt" in "COM1.txt" umbenennen? Daß das nicht erlaubt ist, ist doch klar: Das ist eine reservierte Bezeichnung, die eindeutig sein muß. Es kann nur eine COM1 geben -und das ist keine Datei... MfG Paul
Da bin ich wieder : kann man unter 'C' und Windows Com: Ports 'killen' ?? Hintergrund : Während des Test einer Baugruppe ist die interne Communikation gestört und der Com Port am PC bleibt geöffnet. Dann hilft leider nur ein Reboot und das kostet Zeit. Für die dll, die die Kommunikation aufbaut, habe ich keinen Quellcode.
:
Bearbeitet durch User
Peter II schrieb: > Bernd K. schrieb: >> Unter Linux ist es noch viel verkrampfter die real existierenden tty >> Geräte aufzulisten. > > nicht wirklich, man befragt dafür einfach udev. Und unter Windows benutzt man einfach das Setup-API. Es ist keinesfalls nötig, solche kruden, dummen Lösungen wie die bisher vorgeschlagenen zu verwenden. Der einzige zielführende Lichtblick im ganzen Thread war noch der Hinweis auf WMI. Damit kann man das Problem immerhin tatsächlich sachgerecht lösen. Aber andererseits ist WMI bloß eine ziemlich unnütze Softwareblähung, die letztlich auch wieder auf's Setup-API zurückgreift und dementsprechend nur genau die Informationen liefern kann, die man auch direkt vom Setup-API bekommen kann. Wobei... Es geht bestimmt irgendwie noch ineffizienter als mit WMI. Man könnte z.B. noch eine Schicht mit "Web-Technologien" auf's WMI obendrauf pfropfen. Das läge absolut im Trend... Fakt ist jedenfalls: COM1..4 sind unter Windows keinesfalls "immer da". Allerdings ist aus historischen Gründen "COMx" (mit x=1..9) immer ein reservierter Gerätename, auch wenn die entsprechenden Schnittstellen physisch garnicht existieren. Das ist zwar ein kruder Kompatibilitätshck und alles andere als schön, aber immerhin ein wohldokumentierter Hack...
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.