While I tested Youkko's answer on Windows 10 x64, I got some strange results and looked at the registry of my machine LocationInformation
keys contained lines, such as Port_#0002.Hub_#0003
, so they are connected to the USB hub / port to which the device is connected , and not to the COM port allocated by Windows.
So, in my case, I turned on COM2, which is the hardware port on my motherboard, and it skipped the COM5 port, which I expected, but it was located in the PortName
registry PortName
. I'm not sure if something has changed from the version of Windows you used, but I think that your main problem may not have been checking the null values ββon the keys.
The following slightly modified version works fine on systems with multiple or Windows 7/10 and x32 / 64, and I also added a SerialPort.GetPortNames()
check to make sure the device is accessible and connected to the system before returning:
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; }
source share