Jan18101997 Jan18101997 - 10 months ago 73
C# Question

Mono SerialPort.GetPortNames() actually connected?

I am trying to recive a array of all connected ports with SerialPort.GetPortNames() in Mono but it returns something like this:

(Mac but it should be the same on Linux)

ApfelBuch:~ janwiesemann$ mono "/Users/janwiesemann/Desktop/ports/ports/bin/Debug/ports.exe"

Press any key to continue...

Code used:

string[] ports = SerialPort.GetPortNames();

foreach (string p in ports)
Console.WriteLine (p);

so my qestion is how do i find out which ports are acutally connected to my computer?

Answer Source

As you can see in the mono source code, the SerialPort.GetPortNames() method just enumerates the /dev/tty* nodes:

string[] ttys = Directory.GetFiles("/dev/", "tty*");
foreach (string dev in ttys) {
    if (linux_style){
        if (dev.StartsWith("/dev/ttyS") || dev.StartsWith("/dev/ttyUSB") || dev.StartsWith("/dev/ttyACM"))
            serial_ports.Add (dev);
    } else {
        if (dev != "/dev/tty" && dev.StartsWith ("/dev/tty") && !dev.StartsWith ("/dev/ttyC"))
            serial_ports.Add (dev);

So that's why you're getting all those tty* devices in the output. But it's not so easy to determine which of them actually correspond to a (connected) serial port on your machine.

You can take a look on this answer. They're using an Unix dmesg command there followed by a grep to find out which devices are actually serial ports. They're even trying to figure out which of the serial port is connected on the other side too.

$dmesg | grep ttyS
[    0.872181] 00:06: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A 
[    0.892626] 00:07: ttyS1 at I/O 0x2f8 (irq = 3) is a 16550A 
[    0.915797] 0000:01:01.0: ttyS4 at I/O 0x9800 (irq = 19) is a ST16650V2 
[    0.936942] 0000:01:01.1: ttyS5 at I/O 0x9c00 (irq = 18) is a ST16650V2

Alternatively, you could parse the /proc/tty/drivers file, as explained in this answer.

There are a couple of similar questions about it. Perhaps you can find a solution that suits your needs best.

AFAIK there is no simple way to do this in mono directly, you have to go deeper.


The reason why there is only one /dev/ttyUSB0 item in case of a connected FTDI device seems to be pretty obvious.

In the same method, the linux_style flag value is determined by a simple look-up:

if (dev.StartsWith("/dev/ttyS") || dev.StartsWith("/dev/ttyUSB") || dev.StartsWith("/dev/ttyACM")) {
    linux_style = true;

So if there is a ttyUSB* device available, this flag will be set to true. This affects the device enumeration described above which returns a single item.