Skip to content

Getting Virtual COM Port Names

Peter Foot edited this page Apr 29, 2017 · 2 revisions

Getting Virtual COM Port Names for Remote Bluetooth Devices

On the .NET framework one can use System.IO.Ports.SerialPort.GetPortNames to get a list of the existing COM port names. It does not provide any information however about what remote device the port is used for.

On Win32 to find which virtual COM port is for which remote device use WMI to query the serial ports; when using the Microsoft Bluetooth stack the remote device address is included in the PnP Id. In the following PowerShell example see the remote address as “00803A686519”.

C:\> Get-WmiObject -query "select DeviceID,PNPDeviceID from Win32_SerialPort"
DeviceID     : COM66 
PNPDeviceID  : BTHENUM\{00001101-0000-1000-8000-00805F9B34FB}\7&1D80ECD3&0&00803A686519_C00000003
… …

In C# for instance:

using System.Management;

const string Win32_SerialPort = "Win32_SerialPort";
SelectQuery q = new SelectQuery(Win32_SerialPort);
ManagementObjectSearcher s = new ManagementObjectSearcher(q);
foreach (object cur in s.Get()) {
   ManagementObject mo = (ManagementObject)cur;
   object id = mo.GetPropertyValue("DeviceID");
   object pnpId = mo.GetPropertyValue("PNPDeviceID");
   console.WriteLine("DeviceID:    {0} ", id);
   console.WriteLine("PNPDeviceID: {0} ", pnpId);
   console.WriteLine("");
}//for

Problems with GetDefaultCommConfig, and some info on other stacks

I've had a look at the serial ports on my machines with Bluetooth and can confirm that GetDefaultCommConfig() fails for virtual Serial Ports created by the Microsoft Bluetooth stack. It seems to work ok for Widcomm ports however. (I haven't tested BlueSoleil/Toshiba/etc.)

So it seems the best plan is not to use GetDefaultCommConfig() for the MSFT ports. To identify which ports are which stack, check the values under {"HKEY_LOCAL_MACHINE"}\HARDWARE\DEVICEMAP\SERIALCOMM, which lists the COM port name as the value. If the value name is "\Device\BtModemNNN" then it's the MSFT Bluetooth stack. (Widcomm has "\Device\BtPortNNN").

[HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM](HKEY_LOCAL_MACHINE_HARDWARE_DEVICEMAP_SERIALCOMM) 
"\\Device\\BtPort3"="COM19" 
"\\Device\\BthModem2"="COM25"

Microsoft stack on Windows CE/Mobile

On CE/WM there is no WMI, so one has to resort to inspecting the Registry directly. For instance:

using (var portsK = Registry.LocalMachine.OpenSubKey(
          @"Software\Microsoft\Bluetooth\Serial\Ports", false)) {
   if (portsK == null) {
      console.WriteLine("Bluetooth COM port configuration is missing.");
      return;
   }
   foreach (var devKeyName in portsK.GetSubKeyNames()) {
      BluetoothAddress addr;
      try {
         addr = BluetoothAddress.Parse(devKeyName);
      } catch (FormatException) {
         console.WriteLine("Error: key name is not a device address: '{0}'", devKeyName);
         continue;
      }
      console.WriteLine("DeviceID:    {0} ", addr);
      using (var devKey = portsK.OpenSubKey(devKeyName)) {
         var portN0 = devKey.GetValue("Port");
         var portN1 = portN0 as string;
         var portN = TruncateAtZeros(portN1);
         console.WriteLine("PortName: '{0}'", portN);
      }
   }//for
}
Clone this wiki locally