Pergunta

Existe uma maneira fácil de verificar programaticamente se uma porta COM serial já estiver aberta/sendo usada?

Normalmente eu usaria:

try
{
    // open port
}
catch (Exception ex)
{
    // handle the exception
}

No entanto, eu gostaria de verificar programaticamente para que eu possa tentar usar outra porta COM ou algo assim.

Foi útil?

Solução

Eu precisava de algo semelhante há algum tempo, para procurar um dispositivo.

Eu obtive uma lista de portas COM disponíveis e, em seguida, simplesmente iterei sobre elas, se não lançar uma exceção, tentei me comunicar com o dispositivo. Um pouco difícil, mas funcionando.

var portNames = SerialPort.GetPortNames();

foreach(var port in portNames) {
    //Try for every portName and break on the first working
}

Outras dicas

Foi assim que eu fiz:

      [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);

depois mais tarde

        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();
        }

o Classe de serialport tem um Abrir Método, que lançará algumas exceções. A referência acima contém exemplos detalhados.

Veja também, o Está aberto propriedade.

Um teste simples:

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);
        }
    }
  }
}

Isto é o que funcionou para mim.

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;
    }

Caso você precise capturar exceções de Serialport (aberto):https://docs.microsoft.com/en-us/dotnet/api/system.io.ports.serialport.open?view=netframework-4.7.2

Você pode tentar seguir o código para verificar se uma porta já está aberta ou não. Estou assumindo você não sabe especificamente qual porta você deseja verificar.

foreach (var portName in Serial.GetPortNames()
{
  SerialPort port = new SerialPort(portName);
  if (port.IsOpen){
    /** do something **/
  }
  else {
    /** do something **/
  }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top