2008-10-12 133 views
17

¿Existe alguna manera fácil de comprobar mediante programación si un puerto COM en serie ya está abierto/en uso?C# compruebe si un puerto COM (en serie) ya está abierto

Normalmente me gustaría utilizar:

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

Sin embargo, me gustaría comprobar mediante programación para que pueda intentar usar otro puerto COM o algo así.

Respuesta

11

Necesitaba algo similar hace algún tiempo, para buscar un dispositivo.

Obtuve una lista de puertos COM disponibles y luego simplemente repetí sobre ellos, si no arrojaba una excepción intenté comunicarme con el dispositivo. Un poco duro pero trabajando.

var portNames = SerialPort.GetPortNames(); 

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

Me esperaba una solución más 'elegante' ... pero cuando todo lo demás falla ' ¡use cualquier medio posible para que el programa funcione! –

+1

Para que quede claro para alguien que no conoce el comportamiento de SerialPort, la respuesta anterior no usa el puerto. Abrir que solo comprueba si el CALLER ha abierto el puerto, no si, por ejemplo, otra aplicación lo tiene, para eso intenta comunicarse a través el puerto debe ser hecho y una excepción lanzada - puerto en uso, acceso denegado. – Ken

1

El SerialPort class tiene un método Open, lo que arrojará unas pocas excepciones. La referencia anterior contiene ejemplos detallados.

Vea también, la propiedad IsOpen.

Una prueba sencilla:

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

IsOpen solo funcionará si se llama alguna vez al método Open(). No dirá si el puerto ha sido abierto por otra aplicación. –

+0

¿Cómo se saltea el com1 si no existe? –

+0

El ejemplo usa COM1 como ilustración solamente. Un dispositivo no existente hará que el constructor de SerialPort genere una excepción IOException: "No se pudo encontrar o abrir el puerto especificado". – gimel

-2

Usted puede tratar folloing código para comprobar si un puerto ya está abierto o no. Supongo que no sabes específicamente qué puerto quieres verificar.

foreach (var portName in Serial.GetPortNames() 
{ 
    SerialPort port = new SerialPort(portName); 
    if (port.IsOpen){ 
    /** do something **/ 
    } 
    else { 
    /** do something **/ 
    } 
} 
+10

Sería bueno si las personas dijeran por qué votaron negativamente, para que otras personas puedan saber por qué esto está mal. Supongo que este es el motivo: IsOpen solo se mostrará si se llama alguna vez al método Open(). No dirá si el puerto ha sido abierto por otra aplicación. - Mark Cidade 12 de octubre de 2008 a las 14:28 – jcmcbeth

+0

@jcmcbeth, estás en lo cierto. – Geerten

+0

Si el puerto de comunicación no existe, digamos el puerto 20, aún se puede verificar si está abierto y se devuelve falso, lo que puede inducir a error al desarrollador para intentar abrirlo ... lo mejor es verificar si el puerto existe incluso suponiendo que sea abrir o cerrar – bl4kh4k

12

Esto es cómo lo hice:

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

luego más 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(); 
     } 
+0

¿Cuál es el beneficio de usar esto para sobreponerse a la excepción lanzada al intentar usar SerialPort.Open? – jcmcbeth

+7

Porque no quiere excepciones para controlar el flujo de la aplicación. Es más limpio para tratar de manejar el problema por delante en lugar de lanzar la excepción que manejarla. – Jeff

+4

@Jeff: Sin embargo, corre el riesgo de que si alguien abre el puerto serie en el instante en que lo hace, y cuando lo abre, su programa explote. Al usar excepciones, puede evitar ese desastre potencial. – whatsisname

Cuestiones relacionadas