Domanda

Sto pianificando di riscrivere un'applicazione Win32 (C ++ nativo) in .NET - molto probabilmente usando mono, così posso eseguirlo su Win32, Linux e mac. Il problema che sto cercando di risolvere (che ho sviluppato solo per Win32) è un problema con la definizione della porta seriale. Come si identificano in genere le differenze nella piattaforma quando si suppone che ci sia un solo eseguibile. In particolare, la porta COM è identificata in Windows come COM1 o qualcosa del genere (\. \ COM) ma su Linux sono specificati come qualcosa come / dev / ttyS0.

Si controlla la piattaforma in fase di esecuzione per queste informazioni?

Penso che l'unica differenza sarebbe l'apertura e la chiusura della porta. La lettura e la scrittura sono le stesse.

Forse questa è una domanda più generica in quanto si applica a qualsiasi cosa specifica della piattaforma in mono / .NET.

Come lo gestisci? In qualche risorsa stringa o file di configurazione, o hard-coded e switch basato sulla piattaforma di runtime?

Qualche esempio di codice per questo? Nota che sono uno sviluppatore C ++ e non ho familiarità con tutte le classi disponibili in .NET. c'è un modo per ottenere lo schema di denominazione della porta seriale dal CLR o c'è un modo per ottenere il sistema operativo / la piattaforma dal CLR?

sarebbe stato bello per il CLR essere stato in grado di presentare le porte seriali in modo più indipendente. Forse questo non è possibile.

Grazie, Tim

Modifica

Data l'unica risposta finora, suppongo che dovrei semplicemente provare il
Enumerazione SerialPort.GetPortNames () per prima cosa per vedere se funziona. (su entrambe le piattaforme)

In win32 per i numeri di porta più alti e spesso il dongle USB - non è così semplice come l'enumerazione della porta COM di base.

Riporterò qui i risultati.

È stato utile?

Soluzione

Ho appena scoperto questa discussione e ho pensato che avrei dovuto aggiungere le mie scoperte: a caso, sono anche preoccupato per questo su un Mac. In Windows e Linux (sia VS che Mono) SerialPort.GetPortNames () restituisce un elenco, con le seguenti regole:

1) Windows restituisce un elenco di stringhe come Com1, Com4, perdendo quelle che non esistono (gli adattatori seriali USB sembrano prendere un numero COM in base alla spina a cui sono collegati, in modo coerente) Dal mio scanner per porta seriale :

Scansione COM1 Scansione COM4 Scansione completata

2) Linux restituisce tutte le possibili porte seriali tty che il compilatore della distribuzione Linux ha abilitato. Sembra che siano circa 8 porte, che se si tenta di aprire, verrà generata un'eccezione (dal mio scanner per porte seriali:

Scansione / dev / ttyS0 Scansione / dev / ttyS1 Porta FailedSystem.IO.IOException: errore I / O   at System.IO.Ports.SerialPortStream..ctor (System.String portName, Int32 baudRate, Int32 dataBits, Parity parità, StopBits stopBits, Boolean dtrEnable, Boolean rtsEnable, Handshake handshake, Int32 readTimeout, Int32 writeTimeout, Int32 readBuffer, Int32 readBuffer [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 ()   presso HSMScanner.Program.Main (System.String [] args) [0x00000] Scansione / dev / ttyS2 Porta FailedSystem.IO.IOException: errore I / O   at System.IO.Ports.SerialPortStream..ctor (System.String portName, Int32 baudRate, Int32 dataBits, Parity parità, StopBits stopBits, Boolean dtrEnable, Boolean rtsEnable, Handshake handshake, Int32 readTimeout, Int32 writeTimeout, Int32 readBuffer, Int32 readBuffer [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 ()   presso HSMScanner.Program.Main (System.String [] args) [0x00000] Scansione / dev / ttyS3 Porta FailedSystem.IO.IOException: errore I / O   at System.IO.Ports.SerialPortStream..ctor (System.String portName, Int32 baudRate, Int32 dataBits, Parity parità, StopBits stopBits, Boolean dtrEnable, Boolean rtsEnable, Handshake handshake, Int32 readTimeout, Int32 writeTimeout, Int32 readBuffer, Int32 readBuffer [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 ()   su HSMScanner.Program.Main (System.String [] args) [0x00000]

3) Mac ...

Oh caro oh caro. I Mac (quando è collegata una porta seriale USB e i driver e tutto è ok) non restituiscono nulla su GetPortNames (). Nada. Guardando in / dev / tty, i dispositivi extra appaiono solo quando il dispositivo è collegato e ha nomi come /dev/tty.usbserial-A7006Ro7 sfortunatamente, usando questo nome come argomento per il programma seguito da serial.open dosnt sembra avere alcun effetto.

Scopri di più.

Altri suggerimenti

In .Net, hai bisogno di System.IO.Ports. Nomi come " COM1 " e " / dev / ttyS0 " sono nomi di sistemi operativi casuali. Perché è necessario codificarli? L'utente dovrebbe semplicemente sceglierne uno dall'elenco delle porte disponibili.

Ovviamente, questo elenco viene determinato in fase di esecuzione. In effetti, con gli adattatori da USB a seriale potresti voler considerare la possibilità che l'utente scopra solo dopo aver avviato il programma di aver dimenticato di collegare il suo adattatore da USB a seriale. Ciò significa che dovresti rileggere questo elenco ogni volta che mostri la finestra di dialogo di configurazione. È molto probabile che l'adattatore USB non sia COM1, BTW.

(Non posso garantire la qualità dell'implementazione Mono di SerialPort. Una rapida ricerca su Google mi ha lasciato un po 'preoccupato, ma mettiti alla prova)

Ho dato un'occhiata a questo e sembra che il codice mono per l'enumerazione delle porte seriali non funzionerà su nulla tranne che su Linux.

(da 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 {

Su OSX penso che potresti probabilmente abbinare /dev/tty.* (FreeBSD avrebbe bisogno di / dev / ttyU [0-9] +)

Non posso dire di essere innamorata del modo in cui sceglie il sistema operativo su cui è in esecuzione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top