Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Identify COM port using VID and PID for USB device attached to x64

As following i able to get usb com port names attached to 32bit win7OS machine, by given pid and vid,but when running in x64 it stuck in the following line:

comports.Add((string)rk6.GetValue("PortName"));

This is my code

static List<string> ComPortNames(String VID, String PID)
    {
        String pattern = String.Format("^VID_{0}.PID_{1}", VID, PID);
        Regex _rx = new Regex(pattern, RegexOptions.IgnoreCase);
        List<string> comports = new List<string>();

        RegistryKey rk1 = Registry.LocalMachine;
        RegistryKey rk2 = rk1.OpenSubKey("SYSTEM\\CurrentControlSet\\Enum");

        foreach (String s3 in rk2.GetSubKeyNames())
        {

            RegistryKey rk3 = rk2.OpenSubKey(s3);
            foreach (String s in rk3.GetSubKeyNames())
            {
                if (_rx.Match(s).Success)
                {
                    RegistryKey rk4 = rk3.OpenSubKey(s);
                    foreach (String s2 in rk4.GetSubKeyNames())
                    {
                        RegistryKey rk5 = rk4.OpenSubKey(s2);
                        RegistryKey rk6 = rk5.OpenSubKey("Device Parameters");
                        comports.Add((string)rk6.GetValue("PortName"));
                    }
                }
            }
        }
        return comports;
    }

actual code get here, So how to get com port names in x64, any suggestion?

like image 558
UdayaLakmal Avatar asked Apr 27 '12 12:04

UdayaLakmal


People also ask

How do I find the COM port number of a USB Port?

Follow the instructions to get your COM port number: Open Device Manager (Start → Control Panel → Hardware and Sound → Device Manager) Look in the Device Manager list, open the category "Ports", and find the matching COM Port. Take the number in the bracket behind the port description.

How do I identify a COM port device?

You can check what device is using what COM port from the Device Manager. It will be listed under the hidden devices. From the Device Manager, select View - Show Hidden Devices. Now when you expand the (PORTS) COM ports section you will see all of the COM ports listed there.


2 Answers

While I was testing the answer from Youkko under Windows 10 x64 I was getting some strange results and looking at the registry on my machine the LocationInformation keys contained strings such as Port_#0002.Hub_#0003so they are related to the USB hub / port the device is connected to not the COM port allocated by Windows.

So in my case I was getting COM2 included which is a hardware port on my motherboard and it skipped the COM5 port I was expecting but that was located under the PortName registry key. I'm not sure if something has changed since the version of Windows you were using but I think your main problem might have been not checking for null values on the keys.

The following slightly modified version seems to work fine on a variety or Windows 7 / 10 and x32 / 64 systems and I've also added a to check of SerialPort.GetPortNames() to make sure the device is available and plugged into the system before returning it:

static List<string> ComPortNames(String VID, String PID)
{
    String pattern = String.Format("^VID_{0}.PID_{1}", VID, PID);
    Regex _rx = new Regex(pattern, RegexOptions.IgnoreCase);
    List<string> comports = new List<string>();

    RegistryKey rk1 = Registry.LocalMachine;
    RegistryKey rk2 = rk1.OpenSubKey("SYSTEM\\CurrentControlSet\\Enum");

    foreach (String s3 in rk2.GetSubKeyNames())
    {
        RegistryKey rk3 = rk2.OpenSubKey(s3);
        foreach (String s in rk3.GetSubKeyNames())
        {
            if (_rx.Match(s).Success)
            {
                RegistryKey rk4 = rk3.OpenSubKey(s);
                foreach (String s2 in rk4.GetSubKeyNames())
                {
                    RegistryKey rk5 = rk4.OpenSubKey(s2);
                    string location = (string)rk5.GetValue("LocationInformation");
                    RegistryKey rk6 = rk5.OpenSubKey("Device Parameters");
                    string portName = (string)rk6.GetValue("PortName");
                    if (!String.IsNullOrEmpty(portName) && SerialPort.GetPortNames().Contains(portName))
                        comports.Add((string)rk6.GetValue("PortName"));
                }
            }
        }
    }
    return comports;
}
like image 190
PeterJ Avatar answered Oct 03 '22 14:10

PeterJ


By reading your code, I found out that the current path you're looking at in registry does not contain any information about ports. But I found a way to read it by doing this little change:

    static List<string> ComPortNames(String VID, String PID)
    {
        String pattern = String.Format("^VID_{0}.PID_{1}", VID, PID);
        Regex _rx = new Regex(pattern, RegexOptions.IgnoreCase);
        List<string> comports = new List<string>();

        RegistryKey rk1 = Registry.LocalMachine;
        RegistryKey rk2 = rk1.OpenSubKey("SYSTEM\\CurrentControlSet\\Enum");

        foreach (String s3 in rk2.GetSubKeyNames())
        {

            RegistryKey rk3 = rk2.OpenSubKey(s3);
            foreach (String s in rk3.GetSubKeyNames())
            {
                if (_rx.Match(s).Success)
                {
                    RegistryKey rk4 = rk3.OpenSubKey(s);
                    foreach (String s2 in rk4.GetSubKeyNames())
                    {
                        RegistryKey rk5 = rk4.OpenSubKey(s2);
                        string location = (string)rk5.GetValue("LocationInformation");
                        if (!String.IsNullOrEmpty(location))
                        {
                            string port = location.Substring(location.IndexOf('#') + 1, 4).TrimStart('0');
                            if (!String.IsNullOrEmpty(port)) comports.Add(String.Format("COM{0:####}", port));
                        }
                        //RegistryKey rk6 = rk5.OpenSubKey("Device Parameters");
                        //comports.Add((string)rk6.GetValue("PortName"));
                    }
                }
            }
        }
        return comports;
    }

It did work perfectly. Thank you for your code, by the way... It helped me a lot!

like image 29
Youkko Avatar answered Oct 03 '22 14:10

Youkko