Forum: PC-Programmierung Warum sind Com1..4: immer da ?


von Lutz G. (Firma: KupferKabelbieger GmbH) (lgeis)


Lesenswert?

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 ?

von Stefan F. (Gast)


Lesenswert?

Bei mir ist das nicht so. Du solltest vielleicht mal den konkreten 
Quelltext veröffentlichen.

von Lutz G. (Firma: KupferKabelbieger GmbH) (lgeis)


Lesenswert?

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
von Lutz G. (Firma: KupferKabelbieger GmbH) (lgeis)


Lesenswert?

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 ...

von heute mal ohne (Gast)


Lesenswert?

The EnumPorts function enumerates the ports that are available for 
printing on a specified server ...

von Lutz G. (Firma: KupferKabelbieger GmbH) (lgeis)


Lesenswert?

heute mal ohne schrieb:
> The EnumPorts function enumerates the ports that are available for
> printing on a specified server ...

ja .......

von Stefan F. (Gast)


Lesenswert?

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.

von T.roll (Gast)


Lesenswert?

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.

von Joachim B. (jar)


Lesenswert?

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.

von Hans-Georg L. (h-g-l)


Lesenswert?

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
von nicht"Gast" (Gast)


Lesenswert?

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.

von Peter II (Gast)


Lesenswert?

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.

von Der E. (rogie)


Lesenswert?

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
  }

von nicht"Gast" (Gast)


Lesenswert?

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.

von Bernd K. (prof7bit)


Lesenswert?

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.

von Peter II (Gast)


Lesenswert?

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)

von Peter II (Gast)


Lesenswert?

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.

von Hans-Georg L. (h-g-l)


Lesenswert?

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.

von Flip B. (frickelfreak)


Lesenswert?

Schonmal im die inaktiven geräte anzeigen lassen? ich wette da ist auf 
com3 und 4 ein treiber installiert nur nicht aktiv.

von nicht"Gast" (Gast)


Lesenswert?

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

von Peter II (Gast)


Lesenswert?

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.

von Christian M. (Gast)


Lesenswert?

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

von bluppdidupp (Gast)


Lesenswert?

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

von Lutz G. (Firma: KupferKabelbieger GmbH) (lgeis)


Lesenswert?

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

von W.A. (Gast)


Angehängte Dateien:

Lesenswert?

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?).

von Paul B. (paul_baumann)


Lesenswert?

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

von Lutz G. (Firma: KupferKabelbieger GmbH) (lgeis)


Lesenswert?

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
von c-hater (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.