Using SerialPort Legacy on Windows 8.1

Desde la aparición de Windows 8, se ha escrito mucho sobre la utilización de los espacios de nombres de .NET desde WinRT. Es divertido observar como muchos nos aferramos a estereotipos aparentemente para no tener que cambiar la forma en que utilizamos o hacemos las cosas.

El contenido del siguiente post no es valido si estáis pensando en aplicaciones para la versión RT de Windows… es obvio que difícilmente encontrareis puertos nativos en dispositivos con «RT» ni  USB’s de terceras partes con drivers que los soporten… dicho lo cual :

Esta es una de aquellas discusiones en foros y publicaciones en las que justificamos el porque WinRT no dispone de una implementación para utilizar los eternos «serial ports».

SerialPortOnWindows81

Mas que la motivación por escribir un simple post, me mueve la inquietud generada al conversar con un responsable de RD en el que discutíamos sobre la decisión de desarrollar una solución en WPF por las limitaciones de WinRT para soportar la herencia de antiguos dispositivos unidos con algún  tipo de «Hardware» cuyos drivers llegaron como mucho a «Windows 7».

De hecho la respuesta oficial, es que Windows 8 y posteriores soportan puertos series «CDC» a con WINUSB… la realidad es que no todos los fabricantes han actualizado el «firmware» para que sus  drivers se sustenten en «WinUSB».

Dicho lo cual incluso antes que apareciera la inquietud de acceder a los puertos series nativos desde aplicaciones para la tienda, he utilizado WCF para compartir la comunicación con algún dispositivo de forma concurrente… no olvidéis que al tratarse de una comunicación PeerToPeer si nuestra aplicación «abre» el puerto serie nadie mas podrá acceder a el hasta que liberemos el recurso.

Aquí es donde entra en juego la implementación de un modelo «singlet» que nos permita acceder al envió y recepción de tramas de forma compartida.

Que mas fácil que llamar a un servicio WCF desde Windows 8.x para poder acceder a cualquier objeto que expongamos de .NET, simpre y cuando no estemos en uno de los escenarios donde PCL «Portable Class Library» nos cubra las necesidades.

El siguiente código muestra un punto de partida, entendible, simple y fácil… a petición vuestra podríamos ir desarrollando el tema si es de interés general.

Empezaremos creando un servicio con una simple función de enviar una trama al puerto serie («con total independencia de si es un puerto nativo, CDC USB…etc»)

<ServiceContract()>
Public Interface ISerialPortService
    <OperationContract()>
    Function PortWrite(frame As StringAs String 
End Interface
Imports WcfSerialPort
Public Class SerialPortService
    Implements ISerialPortService
    Public Property mySerialPort As 
                     New System.IO.Ports.SerialPort

    Public Function writePort(frame As StringAs 
        String Implements ISerialPortService.PortWrite
        Try
            mySerialPort.ReadTimeout = 1000
            mySerialPort.NewLine = vbCrLf
            mySerialPort.PortName = "COM4"
            mySerialPort.BaudRate = 1200
            mySerialPort.Open()
            mySerialPort.Write(frame + vbCrLf)
 
            Dim response = ReadResponse()
            mySerialPort.Close()
            Return response
        Catch ex As Exception
            Return ex.Message
        End Try
    End Function
 
    Private Function ReadResponse() As String
        Try
            Return mySerialPort.ReadLine()
        Catch ex As Exception
            Return ex.Message
        End Try
    End Function
 
End Class

Una vez tengamos en servicio en marcha solo tendremos que añadir un proyecto nuevo para la tienda y listo!!

Public NotInheritable Class MainPage
    Inherits Page
    Private miSerialPort As
           New WcfSerialPort.SerialPortServiceClient
 
    Async Sub Btn_Click(sender As Object, 
                             e As RoutedEventArgs)
        Dim result = Await miSerialPort.PortWriteAsync                          ("Hello Windows 8.1 App!!")
        Dim msgbox As 
          New Windows.UI.Popups.MessageDialog(result)
        Await msgbox.ShowAsync()
    End Sub
End Class

Como veis… no muy difícil para empezar 🙂
Me gustara que continuéis en este post, con vuestras conversaciones. Saludos domingueros!!
PepLluis,

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *