Pergunta

Estou pensando em re-escrever uma aplicação Win32 (C ++ nativo) em .NET - provavelmente usando mono para que eu possa executá-lo em Win32, Linux e Mac. O problema que estou tentando resolver (tendo apenas realmente desenvolvido para Win32) é um problema com a definição de porta serial. Como é que se identificam normalmente diferenças na plataforma quando não só é suposto ser um executável. Especificamente, a porta COM é identificado no Windows como COM1 ou algo parecido (\. \ COM), mas no linux que são especificados como algo como / dev / ttyS0.

Será que um verifique a plataforma em tempo de execução para esta informação?

Eu acho que a única diferença seria na abertura e fechamento da porta. A leitura ea escrita é o mesmo.

Talvez esta seja uma questão mais genérica em que se aplica a qualquer material específico da plataforma em mono / .net.

Como você lida com isso? Em algum recurso string ou arquivo de configuração, ou hard-coded e alternar com base na plataforma de execução?

Qualquer amostra de código para isso? Nota sou um desenvolvedor C ++ e não familiarizado com todas as classes disponíveis em .NET. há uma maneira de obter tanto o esquema de nomeação de porta serial do CLR ou há uma maneira de obter o OS / Plataforma do CLR?

que teria sido bom para o CLR ter sido capaz de apresentar as portas seriais de uma forma mais independente. Talvez isso não é possível.

Obrigado, Tim

Editar

Dada a resposta de uma até agora eu acho que eu deveria apenas tentar o
SerialPort.GetPortNames () enumeração primeiro para ver se ele funciona. (Em ambas as plataformas)

Em win32 para os números de porta mais elevadas e ofr o dongle USB - não é tão simples como a enumeração básica porta COM.

Vou relatar os resultados aqui.

Foi útil?

Solução

Só descobri esta discussão, e pensei que alguma coisa apenas para adicionar minhas descobertas: aleatoriamente, eu também estou preocupado com isso em um mac. Em SerialPort.GetPortNames Windows e Linux (na VS e Mono iguais) () retornar uma lista, com as seguintes regras:

1) O Windows retorna uma lista de strings como Com1, Com4, perdendo qualquer que não existem (USB Serial adaptadores parecem ter um número COM baseado na ficha que eles estão conectados, consistentemente) Do meu scanner de porta serial :

Scanning COM1 Scanning COM4 Scanning Complete

2) Linux retorna todas as portas possivelmente tty de série que o compilador do linux distro permitiu. Este parece ser cerca de 8 portas, que se você tentar abrir, irá lançar uma exceção (do meu scanner de porta serial:

Scanning /dev/ttyS0 Scanning /dev/ttyS1 Port FailedSystem.IO.IOException: I/O Error at System.IO.Ports.SerialPortStream..ctor (System.String portName, Int32 baudRate, Int32 dataBits, Parity parity, StopBits stopBits, Boolean dtrEnable, Boolean rtsEnable, Handshake handshake, Int32 readTimeout, Int32 writeTimeout, Int32 readBufferSize, Int32 writeBufferSize) [0x00000] at (wrapper remoting-invoke-with-check) System.IO.Ports.SerialPortStream:.ctor (string,int,int,System.IO.Ports.Parity,System.IO.Ports.StopBits,bool,bool,System.IO.Ports.Handshake,int,int,int,int) at System.IO.Ports.SerialPort.Open () [0x00000] at (wrapper remoting-invoke-with-check) System.IO.Ports.SerialPort:Open () at HSMScanner.Program.Main (System.String[] args) [0x00000] Scanning /dev/ttyS2 Port FailedSystem.IO.IOException: I/O Error at System.IO.Ports.SerialPortStream..ctor (System.String portName, Int32 baudRate, Int32 dataBits, Parity parity, StopBits stopBits, Boolean dtrEnable, Boolean rtsEnable, Handshake handshake, Int32 readTimeout, Int32 writeTimeout, Int32 readBufferSize, Int32 writeBufferSize) [0x00000] at (wrapper remoting-invoke-with-check) System.IO.Ports.SerialPortStream:.ctor (string,int,int,System.IO.Ports.Parity,System.IO.Ports.StopBits,bool,bool,System.IO.Ports.Handshake,int,int,int,int) at System.IO.Ports.SerialPort.Open () [0x00000] at (wrapper remoting-invoke-with-check) System.IO.Ports.SerialPort:Open () at HSMScanner.Program.Main (System.String[] args) [0x00000] Scanning /dev/ttyS3 Port FailedSystem.IO.IOException: I/O Error at System.IO.Ports.SerialPortStream..ctor (System.String portName, Int32 baudRate, Int32 dataBits, Parity parity, StopBits stopBits, Boolean dtrEnable, Boolean rtsEnable, Handshake handshake, Int32 readTimeout, Int32 writeTimeout, Int32 readBufferSize, Int32 writeBufferSize) [0x00000] at (wrapper remoting-invoke-with-check) System.IO.Ports.SerialPortStream:.ctor (string,int,int,System.IO.Ports.Parity,System.IO.Ports.StopBits,bool,bool,System.IO.Ports.Handshake,int,int,int,int) at System.IO.Ports.SerialPort.Open () [0x00000] at (wrapper remoting-invoke-with-check) System.IO.Ports.SerialPort:Open () at HSMScanner.Program.Main (System.String[] args) [0x00000]

3) Macs ...

Oh dear oh querida. Macs (quando uma porta serial USB está conectado e motoristas e tudo são ok) não retornar qualquer sobre os GetPortNames (). Nada. Olhando no / dev / tty, os dispositivos extras aparecem apenas quando o dispositivo está conectado e tem nomes como /dev/tty.usbserial-A7006Ro7 infelizmente, usando esse nome como um argumento para o programa seguido por dosnt serial.open parecem ter qualquer efeito.

Olhando mais para ele.

Outras dicas

Na Net, você precisa System.IO.Ports. Nomes como "COM1" e "/ dev / ttyS0" são nomes OS aleatórios. Por que você precisa para codificar-los? O usuário deve escolher apenas um da lista de portas disponíveis.

Obviamente, você determinar esta lista em tempo de execução. Na verdade, com adaptadores USB-a-série que você pode querer considerar a possibilidade de que apenas os descobre usuário depois de iniciar o programa que ele se esqueceu de ligar o adaptador USB-to-serial. Isso significa que você deve reler esta lista cada vez que você mostrar a janela de configuração. O adaptador USB é bastante provável que não COM1, BTW.

(eu não posso atestar a qualidade da execução Mono de SerialPort. Um rápido Google Search me deixou um pouco preocupado, mas teste você mesmo)

Eu tinha um olhar para isso e parece que o código de mono para enumerar portas seriais não vai trabalhar em qualquer coisa, mas Linux.

(de mcs / class / System / System.IO.Ports / SerialPort.cs)

            public static string [] GetPortNames ()
            {
                    int p = (int) Environment.OSVersion.Platform;
                    List<string> serial_ports = new List<string>();

                    // Are we on Unix?
                    if (p == 4 || p == 128 || p == 6) {
                            string[] ttys = Directory.GetFiles("/dev/", "tty*");
                            foreach (string dev in ttys) {
                                    if (dev.StartsWith("/dev/ttyS") || dev.StartsWith("/dev/ttyUSB"))
                                            serial_ports.Add(dev);
                            }
                    } else {

No OSX Eu acho que você provavelmente poderia igualar /dev/tty.* (FreeBSD precisaria / dev / ttyU [0-9] +)

Eu não posso dizer que estou apaixonado da forma como ele escolhe qual sistema operacional que está sendo executado sob quer ..

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top