2
votes

I have a Windows C# application . The application connects to a RFID card reader over serial port . Though i have given it COM port 3 by default . I land into situations where user's port is not available and his port being used is something different by his windows OS.

My application does give user the ability to change the COM port , but to find which COM port is being used by their operating system , user needs to go to Device Manager and check , which a novice person might not be comfortable with .

Is there a function or a way to find exactly to what port is my RFID card connected to in Windows , so that i can simply display like :

Application Port Set to : COM .... Device Connection Port on OS : COM ....

Also my target framework is 3.5

Edit 1:

Tried using SerialPort.GetPortNames() but it returns an empty string as : System.String[]..

My RFID device is listed under Device Manager ===> Ports(COM & LPT) as Silicon Labs CP210x USB to UART Bridge (COM3)

2
This is a normal problem, serial ports are not plug & play devices. You'll have to complain to the RFID manufacturer and ask for a better way to talk to it.Hans Passant
@HansPassant : I agree with you ... but what i am trying to find here is that once my device has been connected .. can i return to the user myself which port it has been connected to ?user3828453
It the machine has only one serial port, why would it need more, then the choice is rather simple. SerialPort.GetPortNames() gives you a 100% success rate. If it has more then you need somebody that knows what he's doing to remove the extra one. Easy peasy.Hans Passant
using SerialPort.GetPortNames() gives me System.String[] as output ....user3828453
You cannot really get around the need to actually ask for user input of the correct COM port to use. Probing might disrupt activity on ports not used by the RFID reader. How do you handle the situation of two readers attached, and you want to connect to a specific reader? (Believe me, this kind of situation/question eventually happens during the (long) life of a program.)sawdust

2 Answers

1
votes

Hi @user3828453 how about the following and then you can, just use the correct port number which is returned if you still have an empty port than you have to ask the user to go into device manager and update the port via your interface.

private static string GetRFIDComPort()
{
  string portName = "";

  for ( int i = 1; i <= 20; i++ )
  {
    try
    {
      using ( SerialPort port = new SerialPort( string.Format( "COM{0}", i ) ) )
      {
        // Try to Open the port
        port.Open();

        // Ensure that you're communicating with the correct device (Some logic to test that it's your device)

        // Close the port
        port.Close();
      }

    }
    catch ( Exception ex )
    {
      Console.WriteLine( ex.Message );
    }
  }

  return portName;
}
0
votes
using System;
using System.Threading.Tasks;
namespace XYZ{
public class Program
{
    public static void Main(string[] args)  
    {
        Task<string> t = Task.Run( () =>
        { 
            return FindPort.GetPort(10);
        });
        t.Wait();

        if(t.Result == null) 
            Console.WriteLine($"Unable To Find Port");
        else
            Console.WriteLine($"[DONE] Port => {t.Result} Received");


        // Console.ReadLine();
    }
}
}
using System;
using System.IO.Ports;
public static class FindPort
{
    public static string GetPort(int retryCount)
    {
        string portString = null;
        int count = 0;
        while( (portString = FindPort.GetPortString() ) == null) {
            System.Threading.Thread.Sleep(1000);
            if(count > retryCount) break;
            count++;
        }
        return  portString;
    }
    static string GetPortString()
    {
        SerialPort currentPort = null;
        string[] portList = SerialPort.GetPortNames();

        foreach (string port in portList)
        {
            // Console.WriteLine($"Trying Port {port}");
            if (port != "COM1")
            {
                try
                {
                    currentPort = new SerialPort(port, 115200);
                    if (!currentPort.IsOpen)
                    {
                        currentPort.ReadTimeout = 2000;
                        currentPort.WriteTimeout = 2000;

                        currentPort.Open();
                        // Console.WriteLine($"Opened Port {port}");

                        currentPort.Write("connect");

                        string received = currentPort.ReadLine();

                        if(received.Contains("Hub"))
                        {
                            // Console.WriteLine($"Opened Port {port} and received {received}");

                            currentPort.Write("close");
                            currentPort.Close();

                            return port;
                        }
                    }
                }
                catch (Exception e)
                {
                    //Do nothing
                    Console.WriteLine(e.Message);

                    if(currentPort.IsOpen)
                    {
                        currentPort.Write("close");
                        currentPort.Close();
                    }
                }
            }
        }
        // Console.WriteLine($"Unable To Find Port => PortLength : {portList.Length}");
        return null;
    }
}