Laden...

Anzahl der COM-Ports auslesen

20 Antworten
11,896 Aufrufe
Letzter Beitrag: vor 17 Jahren
Anzahl der COM-Ports auslesen

hi. ich habe hier den quelltext eines freundes, der mit einem prog. auf einen com-port zugreifen will. leider hat er den COM6 fest reingeschrieben und nun läuft das prog. nur auf einem rechner, der einen com6 hat.

ich will das jetzt so umschreiben, dass ich die verfügbaren com-ports auf einem rechner feststelle und in einer combo-box zur auswahl anbiete.

meine frage: wie kann ich feststellen, welche com-ports auf einem rechner verfügbar sind ?

danke

Stichwort ist WMI.

Das ist relativ simpel


string[] PortNames = System.IO.Ports.SerialPort.GetPortNames();

[Edit]: Ach verdammt. Ignoriere den Post. GetPortNames listet alle Ports auf die es gibt. Ob nun verfügbar oder nicht.
[Edit2]: Dann wie svenson sagt über WMI

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

Hi,

verstehe ich nicht.

Was heisst verfügbar oder nicht ?

GetPortNames sollte doch eigentlich tun.

Tschüss

danke. ich werd mir die wmi sache mal ansehen

klasse, der wmi code generator funktioniert prima

@a957m:
Die Methode GetPortNames ermittelt nur die Namen die gültig wären für einen COM Port. Auf meinem Laptop wird mir z.B. eine Liste mit den COM-Ports COM1 bis COM16 zurückgeliefert. Sprich, COM16 wäre ein gültiger Anschlussname für meinen Laptop. Aber ob dieser nun auch wirklich vorhanden ist, ist eine andere Sache.

MSDN

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

@a957m:
Die Methode GetPortNames ermittelt nur die Namen die gültig wären für einen COM Port. Auf meinem Laptop wird mir z.B. eine Liste mit den COM-Ports COM1 bis COM16 zurückgeliefert. Sprich, COM16 wäre ein gültiger Anschlussname für meinen Laptop. Aber ob dieser nun auch wirklich vorhanden ist, ist eine andere Sache.

Ich glaub das is schlicht FALSCH was Du erzählst.

return SerialPort.GetPortNames();

...liefert ein String-Array aller auf dem Rechner verfügbaren COM-Ports.
Anders wäre die Funktion einfach nur Unsinn...

Habe es mal eben auf allen Rechnern getestet von mir (2 PCs, 1 Laptop).
Laptop zeigt mir COM1 - COM16 an

  1. PC zeigt COM1 - COM16 an
  2. PC zeigt COM1 - COM4 an.

Und glaub mir, mein Laptop hat keine 16 COM Anschlüsse. Ein Anschluss fest eingebaut. Zwei virtuelle und einer für ActiveSync. Macht vier.

Zur Methode GetPortNames:
Die Methode GetPortNames ist extrem Stumpf. Diese macht nichts weiter als in der Registry den Schlüssel HKLM/HARDWARE/DEVICEMAP/SERIALCOMM auszulesen. Sprich, die Methode ermittelt nur die Namen die auf den entsprechenden System gültig sind! Gültig daswegen, weil irgendwo irgendeine Software den COM Port als gültig in der Registry hinterlegt hat.
Kleiner Test: Ich habe einfach mal einen neuen Schlüssel COM100 hinzugefügt, und schwupps, liefert mir GetPortNames auch den COM Anschluss 100. Aber ich glaube kaum, das mein Laptop ein COM100 hat der auch wirklich verfügbar ist, oder?

Hiermal der Sourcecode zur Methode SerialPort.GetPortNames:


public static string[] GetPortNames()
{
    RegistryKey key = null;
    RegistryKey key2 = null;
    string[] strArray = null;
    new RegistryPermission(RegistryPermissionAccess.Read, @"HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM").Assert();
    try
    {
        key2 = Registry.LocalMachine.OpenSubKey(@"HARDWARE\DEVICEMAP\SERIALCOMM", false);
        if (key2 != null)
        {
            string[] valueNames = key2.GetValueNames();
            strArray = new string[valueNames.Length];
            for (int i = 0; i < valueNames.Length; i++)
            {
                strArray[i] = (string) key2.GetValue(valueNames[i]);
            }
        }
    }
    finally
    {
        if (key != null)
        {
            key.Close();
        }
        if (key2 != null)
        {
            key2.Close();
        }
        CodeAccessPermission.RevertAssert();
    }
    if (strArray == null)
    {
        strArray = new string[0];
    }
    return strArray;
}

Es gibt nur ein Mittel um 100% herauszufinden, ob ein COM-Port wirklich physisch verfügbar ist, und das ist WMI! Basta!

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

  1. PC zeigt COM1 - COM16 an

Was zeigt denn WMI auf dem System an? Bei COM-Ports via PnP wird zumindest die Registry aktualisiert...

WMI ist aber eh der bevorzugte Weg, weil man so noch viel mehr Daten zum Comport bekommt (z.B. maximale Baudrate, HW-Handshake-Support, usw.).

Muss ich eben mal zusammenbasteln. Schreib gleich das Ergebnis...

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

So, hier das Ergebnis:


--- Über GetPortNames() ---
Anschluss: COM3
Anschluss: COM4
Anschluss: COM5
Anschluss: COM6
Anschluss: COM7
Anschluss: COM8
Anschluss: COM9
Anschluss: COM10
Anschluss: COM11
Anschluss: COM12
Anschluss: COM13
Anschluss: COM14
Anschluss: COM15
Anschluss: COM16
Anschluss: COM1
Anschluss: COM100   <-- Hier der manuelle aus der Registry!!
--- Über WMI ---
Anschluss: Kommunikationsanschluss (COM1)
Anschluss: Kommunikationsanschluss (COM2)
Anschluss: Kommunikationsanschluss (COM3)
Anschluss: Kommunikationsanschluss (COM4)

Hier der Code


		private void button1_Click_1(object sender, EventArgs e)
		{
			// Über GetPortNames
			Console.WriteLine("--- Über GetPortNames() ---");
			string[] portNames = System.IO.Ports.SerialPort.GetPortNames();
			foreach (string portName in portNames)
				Console.WriteLine("Anschluss: " + portName);

			// Über WMI
			Console.WriteLine("--- Über WMI ---");
			ManagementObjectSearcher searcher =
				new ManagementObjectSearcher("root\\CIMV2",
				"SELECT * FROM Win32_SerialPort");

			foreach (ManagementObject queryObj in searcher.Get())
			{
				Console.WriteLine("Anschluss: " + queryObj["Caption"].ToString());
			}
		}

[Edit]: Wobei mir hier jetzt sogar auffällt, das COM2 in der Methode GetPortNames gar nicht auftaucht. Naja, ich empfehle dann mal WMI!

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

Also ich verwende diese Methode in all meinen Projekten, inklusive hier im SerialPort Template

Das was Du beschreibst ist mir völlig unbekannt, und Abwandlungen meines SerialPort-Templates laufen auf zig Rechnern in der Produktion bei uns.

Die Leute würden mir als Entwickler einen "Vogel" zeigen bei solch einer Funktionsweise.

Keine Ahnung was bei Euch da anders läuft...

Die Funktionsweise von GetPortNames() ist konzeptionell sicher schwach, da braucht nur ein Treiber mal nicht sauber funzen, und schon hat man eine Leiche in der Registry.

Vorteil ist, dass auch auf nicht WMI-Maschinen funzt. Das wäre aber meines Wissens nur Win98 bzw. Win-NT ohne installiertes WMI. Ich würde immer WMI vorziehen, erfordert aber sicher ein wenig mehr Code.

Keine Ahnung was bei Euch da anders läuft...

Wahrscheinlich nichts. Probiere es doch einfach mal aus! Wenn es dann bei dir wirklich anders laufen sollte, müssten wir mal die Systeme bzw. die Konfiguration vergleichen. Aber glaub mir, das Verhalten wird auch so auf deinem System sein.

Das wäre aber meines Wissens nur Win98 bzw. Win-NT ohne installiertes WMI.

Gibt es das denn noch? Diese "alten" Betriebssysteme beachte ich ehrlich gesagt überhaupt nicht mehr. Hatte auch noch nie einen Kunden der mit so einem OS auf einmal vor mir stand.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

Gibt es das denn noch?

Vermutlich nicht. Ist zumindest für mich kein Grund, GetPortNames zu verwenden. Und wie schon gesagt: Wenn man dem Benutzer die Konfiguration _vollständig _auf gültige Einstellung beschränken will, dann ist WMI sowieso zwingend.

moin,

ich habe das Snippet von Khalid bei mir ausprobiert.

über WMI habe ich nur Thinkpad Modem
über GetPortnames Com3, Com 5-8

irgendetwas schein da nicht zu stimmen, oder?

Raik

Also, ich denke mal, nein ich gehe stark davon aus, das WMI die Wahrheit ausspuckt.

Auf welchen COM-Port liegt denn dein ThinkPad Modem? Hat dein Laptop (ich gehe davon jetzt aus, weil: "ThinkPad Modem") denn weitere physisch vorhandene COM-Ports? Schau mal in den Gerätemanager (Anschlüsse), da dieser ebenfalls über WMI gefüttert wird. Theoretisch dürfte da nur ein COM-Port stehen. Und unter Modems müsste dein ThinkPad Modem auf genau den COM-Port zeigen.

Wenn dies alles zutrifft, wäre so ziemlich 100%ig bewiesen, das die GetPortNames-Methode unzureichend ist. Und du einige Leichen in der Registry stehen hast.

Wenn das nicht der Fall sein sollte, müssten wir darüber noch mal diskutieren 😉

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

Moin Khalid

so habe meinen Laptop untersucht:

Com3 - Thinkpad Modem
Com5 - Bluetooth Kommunikationsanschluss
Com6 - Bluetooth Kommunikationsanschluss
Com7 - Bluetooth Kommunikationsanschluss
Com8 - Bluetooth Modem

nun habe ich mein Handy und mein Headset nicht aktiv. Zeigt denn WMI nur dann an, wenn diese Sachen aktiv sind?

muss ich gleich mal probieren.

Raik