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?
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_#0003
so 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;
}