Herrausfinden der aktuell vorhandenen COM-Schnittstellen
-
KlausB schrieb:
Habe ich vergessen auf das damalige Posting zu atworten

Hallo KlausB,
es handelt sich um diesen Thread: http://www.c-plusplus.net/forum/viewtopic-var-t-is-91717
Hey, das ist fast genau ein Jahr her

Das Problem liegt doch daran: nicht in allen Windosen liegt es an der Stelle
HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMMWie gesagt, unter XP und 2000 klappt das bei mir ganz gut. Hast du da nähere Informationen?
-
Hallo
bei alle Windosen die auf NT basieren stimmt es so
bei Win9X usw ist es nicht ganz so
(oder anderst herum - bin mir nicht mehr ganz sicher wie herum)Mfg
Klaus
-
MFK schrieb:
MSDN schrieb:
The EnumPorts function enumerates the ports that are available for printing on a specified server.
Drucken?
Ich empfehle damit rumzuspielen, bevor man sich ein Urteil bildet... Vielleicht seid ihr ja alle auch zu jung um zu wissen, das es früher auch COM-Port-Drucker gab? (o;
-
junix schrieb:
Ich empfehle damit rumzuspielen, bevor man sich ein Urteil bildet...
Ich habe EnumPorts mal in einem Projekt benutzt und war mit dem Ergebnis nicht zufrieden. Ich wusste nicht mehr, warum, darum habe ich rumgespielt

Ergebnis:
EnumPorts liefert nicht nur serielle Schnittstellen. Das wäre kein Problem, wenn man irgendwie erkennen könnte, welcher Port eine ist und welcher nicht. Dazu habe ich aber auf die Schnelle keine Möglichkeit gefunden.Außerdem liefert EnumPorts Schnittstellen, die gar nicht vorhanden sind. Mein Rechner hier hat weder COM3 noch COM4, und schon gar nicht LPT1, LPT2 und LPT3.
Damit ist EnumPorts IMHO zu Auffinden serieller Schnittstellen komplett ungeeignet.
-
MFK schrieb:
EnumPorts liefert nicht nur serielle Schnittstellen. Das wäre kein Problem, wenn man irgendwie erkennen könnte, welcher Port eine ist und welcher nicht. Dazu habe ich aber auf die Schnelle keine Möglichkeit gefunden.
ganz einfach: Da werden weitere Infos mitgeliefert in denen "COMx" steht... nach COM filtern wirkt wunder (o;
MFK schrieb:
Außerdem liefert EnumPorts Schnittstellen, die gar nicht vorhanden sind. Mein Rechner hier hat weder COM3 noch COM4, und schon gar nicht LPT1, LPT2 und LPT3.
Das ist nach meiner Erfahrung betriebssystemabhängig. Bei NT4 z.B. trifft das zu.
MFK schrieb:
Damit ist EnumPorts IMHO zu Auffinden serieller Schnittstellen komplett ungeeignet.
Naja einzige alternative wäre das versuchte Öffnen aller Schnittstellen. Nur wo hört man da am Besten auf?
-
OK BLABLA nehme ich zurück aber wenn man halt neu ist in der C++ Welt die englische sprache zwar versteht und auch einigermaßen kann hat man doch Probleme seitenlange Texte aus dem Englischen korrekt zu verstehen.
Was mich an dem Artikel zusätzölich gestört hat war das immer vin Printern gesprochen wurde was meines erachtens ja den LPT1 Port betrifft ich aber die Com Schnittstelle suche.Was ja vom Datenformat extrem unterschiedlich ist(parallel und seriel)
Also vielleicht schaffe ich es selber ansonsten würde es mich freuen wenn man mir noch ein paar hilfreiche Tipps geben kann (
das mit der Regisitry durchsuchen war schonmal net schlecht nur wie sieht das mit usb to Serial adaptern aus stehen die dann dauerhaft drin oder nur wenn sie angeschlossen sind?
Und wie durchsuche ich überhaupt die Registry?
Naja ich hoffe habe jetzt nicht soviel unmut gegen mich geschürt das ich vielleicht noch ein paar weiter dämliche Fragen stellen darf.
MfG Felix
-
junix schrieb:
ganz einfach: Da werden weitere Infos mitgeliefert in denen "COMx" steht... nach COM filtern wirkt wunder (o;
Ist irgendwo festgelegt, dass der Gerätename einer seriellen Schnittstelle mit COM anfangen muss?
junix schrieb:
MFK schrieb:
Außerdem liefert EnumPorts Schnittstellen, die gar nicht vorhanden sind. Mein Rechner hier hat weder COM3 noch COM4, und schon gar nicht LPT1, LPT2 und LPT3.
Das ist nach meiner Erfahrung betriebssystemabhängig. Bei NT4 z.B. trifft das zu.
Es kommt noch schlimmer. Ich habe gerade ein wenig mit den BT-Comports herumgespielt. EnumPorts meldet COM5 und COM6, die es nicht gibt. Den frisch eingerichteten COM7 meldet es nicht

OS: Windows XP Professional, SP 2junix schrieb:
Naja einzige alternative wäre das versuchte Öffnen aller Schnittstellen. Nur wo hört man da am Besten auf?
Einer unserer Kunden hatte serielle Schnittstellen im dreistelligen Bereich. Hinzu kommt, dass ein Fehlschlagen des Öffnens nicht bedeutet, dass die Schnittstelle nicht da ist.
-
Ok sowie es aussieht sind da doch noch mehr Probleme mit dem EnumPorts.
KlausB schrieb:
Hallo
bei alle Windosen die auf NT basieren stimmt es so
bei Win9X usw ist es nicht ganz so
(oder anderst herum - bin mir nicht mehr ganz sicher wie herum)Mfg
KlausWenn ich das richtig verstehe gibt es bei der Registry nur 2 möglichkeiten
entweder 98, me oder 2000 und XP ist es nicht möglich das betriebssystem auszulesen und dann den entsprechenden Registryschlüssel zu durchforsten?
ist auf jedenfall effektiver als 200 Com Ports zu testen.
MfG Felix
-
bierber schrieb:
ist es nicht möglich das betriebssystem auszulesen
GetVersionEx
und dann den entsprechenden Registryschlüssel zu durchforsten?
RegOpenKeyEx, RegEnumValue usw. Der BCB hat aber bestimmt eine Klasse dafür.
-
TRegistry
-
Ich mache dies immer damit:
//--------------------------------------------------------------------------- void TfrmOptions::LoadCommPortsList() { COMMCONFIG CommConfig; AnsiString saTemp; DWORD dwSize = sizeof(COMMCONFIG); CommConfig.dwSize = sizeof(COMMCONFIG); for(int iPort = 1; iPort <= MAX_COMM_PORTS; ++iPort) { saTemp.sprintf("COM%1u", iPort); if(GetDefaultCommConfig(saTemp.c_str(), &CommConfig, &dwSize)) { saTemp.sprintf("COM%1u (%s)", iPort, GetCommProviderSubTypeText(CommConfig.dwProviderSubType).c_str()); cbxComPort_Imes->Items->Add(saTemp); } else { saTemp.sprintf("COM%1u (n/a)", iPort); cbxComPort_Imes->Items->Add(saTemp); } } } //--------------------------------------------------------------------------- AnsiString __fastcall TfrmOptions::GetCommProviderSubTypeText(DWORD dwProviderSubType) { switch(dwProviderSubType) { case PST_FAX: return AnsiString("FAX"); case PST_LAT: return AnsiString("LAT"); case PST_MODEM: return AnsiString("Modem"); case PST_NETWORK_BRIDGE: return AnsiString("Network bridge"); case PST_PARALLELPORT: return AnsiString("Parallel"); case PST_RS232: return AnsiString("RS232"); case PST_RS422: return AnsiString("RS422"); case PST_RS423: return AnsiString("RS423"); case PST_RS449: return AnsiString("RS449"); case PST_SCANNER: return AnsiString("Scanner"); case PST_TCPIP_TELNET: return AnsiString("Telnet®"); case PST_X25: return AnsiString("X.25"); case PST_UNSPECIFIED: default: return AnsiString("?"); } }Gruß Nighthero
-
MFK schrieb:
junix schrieb:
ganz einfach: Da werden weitere Infos mitgeliefert in denen "COMx" steht... nach COM filtern wirkt wunder (o;
Ist irgendwo festgelegt, dass der Gerätename einer seriellen Schnittstelle mit COM anfangen muss?
Nicht das ich wüsste. Ging bis dato aber immer davon aus...
MFK schrieb:
junix schrieb:
MFK schrieb:
Außerdem liefert EnumPorts Schnittstellen, die gar nicht vorhanden sind. Mein Rechner hier hat weder COM3 noch COM4, und schon gar nicht LPT1, LPT2 und LPT3.
Das ist nach meiner Erfahrung betriebssystemabhängig. Bei NT4 z.B. trifft das zu.
Es kommt noch schlimmer. Ich habe gerade ein wenig mit den BT-Comports herumgespielt. EnumPorts meldet COM5 und COM6, die es nicht gibt. Den frisch eingerichteten COM7 meldet es nicht

OS: Windows XP Professional, SP 2Das ist schlecht. Wusste ich bis jetzt auch nicht so. Überrascht mich ehrlich gesagt etwas...
MFK schrieb:
junix schrieb:
Naja einzige alternative wäre das versuchte Öffnen aller Schnittstellen. Nur wo hört man da am Besten auf?
Einer unserer Kunden hatte serielle Schnittstellen im dreistelligen Bereich. Hinzu kommt, dass ein Fehlschlagen des Öffnens nicht bedeutet, dass die Schnittstelle nicht da ist.
Korrekt. Aber zumindest bedeutet es, dass die Schnittstelle nicht verfügbar ist, da sie belegt wird. Und das reicht ja eigentlich schon. Denn es macht ja keinen Sinn, dem Benutzer die Möglichkeit zu geben, Schnittstellen zu kopnfigurieren, die nicht verfügbar sind?
Nightheros Ansatz hat 2 Nasen:
a) er geht ebenfalls davon aus, dass die Schnittstellen mit COM anfangen
b) Woher krieg ich MAX_COMM_PORTS?
-
junix schrieb:
Nicht das ich wüsste. Ging bis dato aber immer davon aus...
Ich eigentlich auch...
junix schrieb:
Überrascht mich ehrlich gesagt etwas...
Mich wundert gerade bei den Funktionen, die mit seriellen Schnittstellen zu tun haben, gar nichts mehr. Ich habe z.B. auch feststellen müssen, dass auf einigen Maschinen BuildCommDCB bei COM-Ports über 9 nicht mehr funtionierte

MFK schrieb:
Aber zumindest bedeutet es, dass die Schnittstelle nicht verfügbar ist, da sie belegt wird. Und das reicht ja eigentlich schon. Denn es macht ja keinen Sinn, dem Benutzer die Möglichkeit zu geben, Schnittstellen zu kopnfigurieren, die nicht verfügbar sind?
In dem konkreten Projekt war es ein Problem. Ich brauchte für einen Konfigurationsdialog die tatsächlich vorhandenen Schnittstellen, auch wenn die gerade durch irgendeine andere Anwendung belegt war. Denn so was ist ja nicht zwangsläufig von Dauer.
Nightheros Ansatz hat 2 Nasen:
a) er geht ebenfalls davon aus, dass die Schnittstellen mit COM anfangen
b) Woher krieg ich MAX_COMM_PORTS?Ich hab das gerade mal getestet: GetDefaultCommConfig liefert mir für alles, was über "COM1" hinausgeht, FALSE. GetLastError ist 87, Invalid Parameter.
-
MFK schrieb:
Mich wundert gerade bei den Funktionen, die mit seriellen Schnittstellen zu tun haben, gar nichts mehr. Ich habe z.B. auch feststellen müssen, dass auf einigen Maschinen BuildCommDCB bei COM-Ports über 9 nicht mehr funtionierte

Das liegt daran, das bei comports ab com10 der Gereätebezeichner so auusehen muß:
"\\\\.\\Com10"Es funzt aber auch ab Comport 1.
-
Burkhi schrieb:
Das liegt daran, das bei comports ab com10 der Gereätebezeichner so auusehen muß:
"\\\\.\\Com10"Ich weiß. Aber auch damit schlug BuildCommDCB fehl. Wie gesagt, nicht auf allen Maschinen.
-
MAX_COMM_PORTS ist einfach ein #define, je nach dem, wie weit man die Suche ausdehnen möchte.
"\\\.\\Com10" funktioniert bei mir überhaupt nicht, da bekomme ich immer GetLastError() == 87
Gruß Nighthero
-
Auf Code Project ist ein recht ausführliches Beispiel, sollte man sich vielleicht mal ansehen: http://codeproject.com/system/setupdi.asp?df=100&forumid=4368&exp=0&select=240059
Gruß Nighthero
-
Hallo
hab mal den Link von Nighthero besucht und die Datei heruntergeladen nur das steht was drin was ich nicht verstehe damit das läuft und zwar folgendes.
Ich soll die EnumalSerial.cpp mit der setupapi.lib verlinken
hört sich erstmal gut an aber wie verlinke ich etwas mit etwas anderem er hat nur angegeben wie man es unter Visual C++ macht
Vielleicht weiß einer von euch wie es geht oder was man wo machen kann?
Merci schonmal Felix
-
wie soll das system denn auf einen port zugreifen können der gar nicht existiert. daher ist der getlasterror (87, INVALID_HANDLE_VALUE) ja auch ganz logisch.
am einfachsten ist es, in ner schleife von 1 bis 256 (das ist glaub ich das maximum was geht im system) zu laufen und zu versuchen jeden port zu öffnen. dort wo es gelingt, existiert der port. wo der aufruf fehlschlägt, dem zu folge nicht. letzt sich schön mit nem barcode-reader testen der usb->com macht. einfach immer an nen anderen usb-anschluss haengen und windows generiert jedesmal nen neuen virtuellen com-port...
HANDLE Com; AnsiString PortName; // alle Com-Ports bestimmen for (int i = 1; i <= 256; ++i) { PortName = "COM" + IntToStr(i); // Port öffnen Com = ::CreateFile(PortName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (Com != INVALID_HANDLE_VALUE) { // alle gefundenen Ports in ne Listbox packen ListBox1->Items->Add(PortName); // Port wieder schliessen PurgeComm(Com, PURGE_RXABORT); CloseHandle(Com); } }
-
"\\\.\\Com10" war natürlich nur beispielhaft für die Syntax, es schlägt bei mir auf allen Ports fehl!
saTemp.sprintf("\\\\.\\Com%1u", iPort);