我计划用.NET重写一个Win32应用程序(原生C++) --很可能是使用mono,这样我就可以在Win32、Linux和mac上运行它了。我试图解决的问题(真正为Win32开发的)是串行端口定义的问题。当只有一个可执行文件时,人们通常如何识别平台的差异。具体来说,在windows中,COM端口被标识为COM1或类似的东西(.\COM),但在linux上,它们被指定为类似于/dev/ttyS0的内容。
是否有人在运行时检查平台以获取此信息?
我认为唯一的区别是港口的开放和关闭。读写是一样的。
也许这是一个更一般的问题,因为它适用于mono/.NET中的任何特定于平台的东西。
你是怎么处理这个问题的?在一些字符串资源或配置文件中,还是基于运行时平台硬编码和切换?
有没有这方面的代码样本?注:我是一名C++开发人员,并不熟悉.NET中的所有类。有没有办法从CLR获得串行端口命名方案,或者有办法从CLR获得操作系统/平台?
如果CLR能够以一种更独立的方式呈现串行端口,那就太好了。也许这是不可能的。
谢谢,蒂姆
编辑
给出到目前为止的唯一响应,我想我应该尝试
SerialPort.GetPortNames()枚举,看看它是否工作。(在两个平台上)
在win32中,对于更高的端口号,或者在USB加密狗中-它不像基本的COM端口枚举那么简单。
我将在这里报告调查结果。
发布于 2009-05-14 16:21:02
我刚刚发现了这个线程,并认为我没有必要添加我的发现:随机地说,我也担心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...
哦天啊哦天啊。Mac(当插入usb串口并且驱动程序和一切正常时)不会在GetPortNames()上返回任何东西。什么都没有。查看/dev/tty,额外的设备只有在插入设备时才会出现,不幸的是,这些设备的名称类似于/dev/tty.usbserial-A7006Ro7,使用此名称作为程序的参数,后跟serial.open似乎没有任何效果。
调查得更深入一些。
发布于 2009-01-12 12:04:49
在.Net中,您需要System.IO.Ports。像"COM1“和"/dev/ttyS0”这样的名称是随机的操作系统名称。为什么需要对它们进行硬编码?用户只需从可用端口列表中选择一个。
显然,这个列表是在运行时确定的。实际上,对于USB转串行适配器,您可能需要考虑这样一种可能性,即用户只有在启动程序后才发现他忘记连接USB转串行适配器。这意味着您应该在每次显示配置对话框时重新阅读此列表。USB适配器很可能不是COM1,BTW。
(我不能保证SerialPort的单声道实现的质量。快速的谷歌搜索让我有点担心,但测试一下你自己)
发布于 2011-07-13 20:50:05
我看过这一点,似乎枚举串行端口的mono代码只能在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/ttyU0-9+)
我也不能说我对它选择在哪种操作系统上运行的方式很感兴趣。
https://stackoverflow.com/questions/434494
复制相似问题