C # vérifier si un port COM (série) est déjà ouvert
-
10-07-2019 - |
Question
Existe-t-il un moyen simple de vérifier par programme si un port COM série est déjà ouvert / en cours d'utilisation?
Normalement, j'utiliserais:
try
{
// open port
}
catch (Exception ex)
{
// handle the exception
}
Toutefois, je souhaite effectuer une vérification par programmation afin de pouvoir utiliser un autre port COM ou un autre port de ce type.
La solution
J'avais besoin de quelque chose de similaire il y a quelque temps, pour rechercher un appareil.
J'ai obtenu une liste des ports COM disponibles et ensuite simplement itéré sur eux, s'il ne lève pas une exception, j'ai essayé de communiquer avec le périphérique. Un peu rude mais fonctionnel.
var portNames = SerialPort.GetPortNames();
foreach(var port in portNames) {
//Try for every portName and break on the first working
}
Autres conseils
Voici comment je l'ai fait:
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
internal static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode, IntPtr securityAttrs, int dwCreationDisposition, int dwFlagsAndAttributes, IntPtr hTemplateFile);
puis plus tard
int dwFlagsAndAttributes = 0x40000000;
var portName = "COM5";
var isValid = SerialPort.GetPortNames().Any(x => string.Compare(x, portName, true) == 0);
if (!isValid)
throw new System.IO.IOException(string.Format("{0} port was not found", portName));
//Borrowed from Microsoft's Serial Port Open Method :)
SafeFileHandle hFile = CreateFile(@"\\.\" + portName, -1073741824, 0, IntPtr.Zero, 3, dwFlagsAndAttributes, IntPtr.Zero);
if (hFile.IsInvalid)
throw new System.IO.IOException(string.Format("{0} port is already open", portName));
hFile.Close();
using (var serialPort = new SerialPort(portName, 115200, Parity.None, 8, StopBits.One))
{
serialPort.Open();
}
La la classe SerialPort a une Ouvrir une méthode, qui jettera quelques exceptions. La référence ci-dessus contient des exemples détaillés.
Voir aussi le IsOpen propriété.
Un test simple:
using System;
using System.IO.Ports;
using System.Collections.Generic;
using System.Text;
namespace SerPort1
{
class Program
{
static private SerialPort MyPort;
static void Main(string[] args)
{
MyPort = new SerialPort("COM1");
OpenMyPort();
Console.WriteLine("BaudRate {0}", MyPort.BaudRate);
OpenMyPort();
MyPort.Close();
Console.ReadLine();
}
private static void OpenMyPort()
{
try
{
MyPort.Open();
}
catch (Exception ex)
{
Console.WriteLine("Error opening my port: {0}", ex.Message);
}
}
}
}
C'est ce qui a fonctionné pour moi.
private string portName { get; set; } = string.Empty;
/// <summary>
/// Returns SerialPort Port State (Open / Closed)
/// </summary>
/// <returns></returns>
internal bool HasOpenPort()
{
bool portState = false;
if (portName != string.Empty)
{
using (SerialPort serialPort = new SerialPort(portName))
{
foreach (var itm in SerialPort.GetPortNames())
{
if (itm.Contains(serialPort.PortName))
{
if (serialPort.IsOpen) { portState = true; }
else { portState = false; }
}
}
}
}
else { System.Windows.Forms.MessageBox.Show("Error: No Port Specified."); }
return portState;
}
Dans le cas où vous devez capturer des exceptions SerialPort (Open): https: //docs.microsoft.com/en-us/dotnet/api/system.io.ports.serialport.open?view=netframework-4.7.2
Vous pouvez essayer le code suivant pour vérifier si un port est déjà ouvert ou non. Je suppose que vous ne savez pas précisément quel port vous souhaitez vérifier.
foreach (var portName in Serial.GetPortNames()
{
SerialPort port = new SerialPort(portName);
if (port.IsOpen){
/** do something **/
}
else {
/** do something **/
}
}