Inhaltsverzeichnis
Warum dieses Tutorial?
Immer wieder stelle ich fest, dass in einer entwickelten Software, die die seriellen Schnittstellen unterstützt, einfach alle erdenklichen COM-Ports angegeben werden. Vor allem auch Ports, die auf dem Computer gar nicht zur Verfügung stehen. Wird ein solcher Port dann ausgesucht, kommt es entweder innerhalb des Programms zu einer Meldung, dass es den ausgewählten Port nicht gibt oder es kommt sogar zum Absturz des Programms. Das muss alles nicht sein. Auf eine einfache Art und Weise ist es möglich, nur die COM-Ports innerhalb eines Programms anzugeben, die auf dem jeweiligen Computer zur Verfügung stehen.
Entwicklungsumgebung
Für das hier zu beschreibende Beispiel benutze ich Visual C# 2008. Da dieses Beispiel sehr einfach gehalten ist, kann es schnell auf eine andere Programmiersprache portiert werden. Außerdem ist C# 2008 unter der folgenden Adresse kostenlos zu beziehen. [1]
Grundgedanke
Um alle 255 möglichen COM-Schnittstellen zu finden, soll eine Schnittstelle nach der anderen geöffnet werden. Lässt sie sich öffnen, dann schreibe sie in eine Liste, ansonsten mache nichts und nehme die nächste Schnittstelle. Das ganze muss beim Programmstart durch geführt werden. Natürlich könnten auch die installierten Schnittstellen aus der Regetry ausgelesen werden. Meine Erfahrung zeigt aber, dass dieses Vorgehen oft scheitert, da in der Regestry Ports noch eingetragen sind, die in Wirklichkeit nicht mehr vorhanden sind (es wird Software nicht deinstalliert, sondern nur von Hand gelöscht und somit werden die Regestry-Einträge auch nicht gelöscht).
Das Programm
Beim Programmstart wird über eine FOR-Schleife versucht, alle 255 möglichen COM-Ports zu öffnen. Dieses geschieht in der try-Anweisung. Gibt es auf dem Computer die jeweilige Schnittstelle nicht, läuft es auf einen Fehler, der in der catch-Anweisung abgefangen wird. Da aber bei einem Fehler nichts gemacht werden soll, ist die catch-Anweisung leer und es wird versucht, den nächsten COM-Port zu öffnen. Beim Öffnen eines COM-Ports gibt es aber etwas zu beachten. Der jeweilige Port besteht nicht nur aus einer Ziffer (1-255), sondern aus COM1 –COM255. Aus diesem Grunde muss der Portname aus dem String COM und der jeweiligen Nummer zusammen gesetzt werden. Dieses wird mit der Zeile Port = „COM“ + i; gemacht. Der so definierte Portname wird zugeordnet und anschließend wird dieser COM-Port geöffnet. Gibt es nun diesen Port nicht, tritt ein Fehler auf und es wird gleich in die catch-Anweisung gesprungen. Da dort aber nichts durchgeführt werden soll, wird i um 1 erhöht und somit wird versucht, den nächsten COM-Port zu öffnen. Ließ sich nun aber der Port öffnen, wird vor dem Schließen des Ports dieser in die ComboBox cmdPortName hinzugefügt. Die Variable Port muss als String deklariert werden.
for (int i = 1; i < 256; i++) { try {// Öffne den jeweiligen COM-Port und trage den Gefundenen in die ComboBox ein Port = "COM" + i; // Zusammensetzung des Ports aus COM und der Ziffer ComPort.PortName = (Port); // Zuordnung des Ports ComPort.Open(); // Öffnen des Ports cmdPortName.Items.Add(Port); // Gefundener Port in ComboBox hinzufügen ComPort.Close(); // Schließen des Ports } catch { // Der Com-Port kann nicht geöffnet werden //MessageBox.Show("COM-Port kann nicht geöffnet werden!"); } }
Das ist schon das ganze Prinzip, um nur die zur Verfügung stehenden COM-Ports des Computers zu finden.
Zur Vollständigkeit hier das ganze Programm
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } //****************************************************************** //* Programm beenden * //****************************************************************** private void button3_Click(object sender, EventArgs e) { Application.Exit(); /* Komplette Programm beenden */ } //****************************************************************** //* Hauptprogramm * //****************************************************************** private void Form1_Load(object sender, EventArgs e) { String Port; for (int i = 1; i < 256; i++) { try {// Öffne den jeweiligen COM-Port und trage den Gefundenen in die ComboBox ein Port = "COM" + i; ComPort.PortName = (Port); ComPort.Open(); cmdPortName.Items.Add(Port); ComPort.Close(); } catch { // Der Com-Port kann nicht geöffnet werden //MessageBox.Show("COM-Port kann nicht geöffnet werden!"); } } // Button setzen Exit.Enabled = true; Connect.Enabled = true; Disconnect.Enabled = false; // Zur Verfügung stehende COM-Ports suchen /* Voreinstellungen für den zu öffnenden COM-Port */ cmdPortName.Items.Add("No COM-Port haved available"); cmdPortName.SelectedIndex = 0; cmdBaudrate.Items.Add("4800"); /* Baudrate */ cmdBaudrate.Items.Add("9600"); cmdBaudrate.Items.Add("19200"); cmdBaudrate.Items.Add("38400"); cmdBaudrate.Items.Add("57600"); cmdBaudrate.Items.Add("115200"); cmdBaudrate.SelectedIndex = 1; /* Setzen auf 9600 Baud */ cmdDataBits.Items.Add("4"); /* Anzahl der Datenbits*/ cmdDataBits.Items.Add("5"); cmdDataBits.Items.Add("6"); cmdDataBits.Items.Add("7"); cmdDataBits.Items.Add("8"); cmdDataBits.SelectedIndex = 4; /* Setzen auf 8 Datenbits */ cmdParity.Items.Add("Even"); /* Parity */ cmdParity.Items.Add("Odd"); cmdParity.Items.Add("None"); cmdParity.Items.Add("Marquage"); cmdParity.Items.Add("Plaque"); cmdParity.SelectedIndex = 2; /* Setzen auf None */ cmdStopBits.Items.Add("1"); /* Anzahl der Stopbits */ cmdStopBits.Items.Add("1.5"); cmdStopBits.Items.Add("2"); cmdStopBits.SelectedIndex = 0; /* Setzen auf 1 Stopbit */ } //****************************************************************** //* COM-Port öffnen * //****************************************************************** private void button2_Click(object sender, EventArgs e) { // Button setzen Connect.Enabled = false; Disconnect.Enabled = true; Exit.Enabled = false; // Setzen der Parameter des COM-Ports gemäss gewählten Einstellungen if (ComPort.IsOpen) { ComPort.Close(); // COM-Port ist geöffnet ==> schließen } else { // COM-Port kann nun geöffnet werden ComPort.BaudRate = int.Parse(cmdBaudrate.Text); ComPort.DataBits = int.Parse(cmdDataBits.Text); ComPort.StopBits = (System.IO.Ports.StopBits)Enum.Parse(typeof(System.IO.Ports.StopBits), cmdStopBits.Text); ComPort.Parity = (System.IO.Ports.Parity)Enum.Parse(typeof(System.IO.Ports.Parity), cmdParity.Text); ComPort.PortName = cmdPortName.Text; ComPort.ReceivedBytesThreshold = 1; ComPort.NewLine = "\0x13"; ComPort.WriteTimeout = 1000; ComPort.ReadTimeout = 5000; ComPort.DtrEnable = true; ComPort.RtsEnable = false; //ComPort.Open(); } } //*************************************************************************** //* COM-Port schließen * //*************************************************************************** private void button1_Click(object sender, EventArgs e) { ComPort.Close(); // Button setzen Disconnect.Enabled = false; Connect.Enabled = true; Exit.Enabled = true; } private void textBox2_TextChanged(object sender, EventArgs e) { } } }
Screenshots des Programms
Nach dem Programmstart stehen in der ComboBox alle zur Verfügung stehenden COM-Ports.
COM-Port ist ausgewählt. Alle anderen Parameter sind eingestellt.
COM-Port ist geöffnet. Die Button sind inaktiv und werden erst wieder aktiv, wenn die Verbindung getrennt wurde.
Das Programm samt Sourcecode kann hier [2] im Downloadbereich herunter geladen werden
Lizenz-Bedingung
Dieses Programm steht unter der folgenden CC BY-NC-SA-Lizenz .Dieser Quelltext einschließlich der darin verlinkten Inhalte steht unter der CC by-nc-sa Lizenz http://creativecommons.org/licenses/by-nc-sa/3.0/de/
Das bedeutet: Es ist gestattet: das Werk vervielfältigen, verbreiten und öffentlich zugänglich machen, Abwandlungen bzw. Bearbeitungen des Inhaltes anfertigen zu den folgenden Bedingungen: Namensnennung. Sie müssen den Namen des Autors/Rechteinhabers in der von ihm festgelegten Weise nennen. Keine kommerzielle Nutzung. Dieses Werk darf nicht für kommerzielle Zwecke verwendet werden. Weitergabe unter gleichen Bedingungen. Wenn Sie den lizenzierten Inhalt bearbeiten oder in anderer Weise umgestalten, verändern oder als Grundlage für einen anderen Inhalt verwenden, dürfen Sie den neu entstandenen Inhalt nur unter Verwendung von Lizenzbedingungen weitergeben, die mit denen dieses Lizenzvertrages identisch oder vergleichbar sind.