3

Win32 アプリケーション (ネイティブ C++) を .NET で書き直すことを計画しています。おそらく mono を使用しているため、Win32、Linux、および Mac で実行できます。私が解決しようとしている問題 (実際には Win32 用にしか開発されていません) は、シリアル ポートの定義に関する問題です。実行可能ファイルが 1 つしかないと想定されている場合、通常、プラットフォームの違いをどのように識別しますか。具体的には、COM ポートは Windows では COM1 など (\.\COM) として識別されますが、Linux では /dev/ttyS0 などとして指定されます。

この情報について、実行時にプラットフォームをチェックしますか?

唯一の違いは、ポートの開閉だけだと思います。読み書きは同じです。

おそらくこれは、モノ/.NET のプラットフォーム固有のものに適用されるという点で、より一般的な質問です。

これをどのように処理しますか?一部の文字列リソースまたは構成ファイルで、またはランタイム プラットフォームに基づいてハードコーディングおよびスイッチしますか?

このためのコードサンプルはありますか? 私は C++ 開発者であり、.NET で使用できるすべてのクラスに精通しているわけではありません。CLR からシリアル ポートの命名スキームを取得する方法はありますか、または CLR から OS/プラットフォームを取得する方法はありますか?

CLR がシリアル ポートをより独立した方法で提供できればよかったのにと思います。多分それは不可能です。

ありがとう、ティム

編集


これまでの 1 つの応答を考えると、最初に SerialPort.GetPortNames() 列挙を試して、それが機能するかどうかを確認する必要があると思います。(両方のプラットフォームで)

より高いポート番号と USB ドングルの win32 では、基本的な COM ポートの列挙ほど単純ではありません。

ここで調査結果を報告します。

4

3 に答える 3

4

.Net では、System.IO.Ports が必要です。「COM1」や「/dev/ttyS0」などの名前はランダムな OS 名です。なぜそれらをハードコーディングする必要があるのですか? ユーザーは、使用可能なポートのリストから 1 つを選択する必要があります。

明らかに、実行時にこのリストを決定します。実際、USB-to-serial アダプタの場合、ユーザーがプログラムを起動した後で初めて、USB-to-serial アダプタを接続するのを忘れたことに気付く可能性を考慮する必要があるかもしれません。つまり、設定ダイアログを表示するたびに、このリストを読み直す必要があります。USB アダプタはおそらく COM1 ではありません。

(SerialPort の Mono 実装の品質を保証することはできません。簡単な Google 検索で少し心配になりましたが、自分でテストしてください)

于 2009-01-12T12:04:48.970 に答える
3

これを見たところ、シリアルポートを列挙するためのモノコードはLinux以外では機能しないようです。

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

OSX では、おそらく /dev/tty.* に一致すると思います (FreeBSD には /dev/ttyU[0-9]+ が必要です)。

どのOSで実行されているかを選択する方法に夢中になっているとは言えません..

于 2011-07-13T12:50:04.747 に答える
1

このスレッドを発見したばかりで、自分の発見を追加するしかないと思いました。ランダムに、Mac でもこれについて心配しています。Windows と Linux (VS と Mono の両方) では、SerialPort.GetPortNames() は次のルールでリストを返します。

1) Windows は Com1、Com4 などの文字列のリストを返しますが、存在しないものはすべて欠落しています (USB シリアル アダプタは、接続されているプラ​​グに基づいて常に COM 番号を取得しているようです)。私のシリアル ポート スキャナから:

Scanning COM1 Scanning COM4 Scanning Complete

2) Linux は、Linux ディストリビューションのコンパイラが有効にした可能性のあるすべての tty シリアル ポートを返します。これは約8つのポートのようで、開こうとすると例外がスローされます(私のシリアルポートスキャナーから:

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) マック...

ああ、ああ、ああ。Mac (USB シリアル ポートが接続され、ドライバーとすべてが正常な場合) は、GetPortNames() で何も返しません。なだ。/dev/tty を見ると、デバイスが接続されている場合にのみ追加のデバイスが表示され、残念ながら /dev/tty.usbserial-A7006Ro7 のような名前が付けられています。この名前をプログラムへの引数として使用し、その後に serial.open が続くようには見えません。効果があります。

もっと調べてみます。

于 2009-05-14T16:21:01.833 に答える