8
votes

I'm looking for a way to determine if a COM is a standard COM or if it's an SPP COM, also known as a cable replacement bluetooth adapter for a COM device.

I have a device which works both in USB (COM -> USB) and Bluetooth, and the Bluetooth interface works with SPP.

I am currently using System.IO.Ports.SerialPort.GetPortNames() to get the COMs.

Is there a way to determine whether or not it's a connected with Bluetooth or USB?

SOLUTION:

System.Management.ManagementObjectSearcher Searcher = new System.Management.ManagementObjectSearcher("Select * from WIN32_SerialPort");
foreach (System.Management.ManagementObject Port in Searcher.Get())
{
    foreach (System.Management.PropertyData Property in Port.Properties)
    {
        Console.WriteLine(Property.Name + " " + (Property.Value == null ? null : Property.Value.ToString()));
    }
}

And the output is something similar:

Availability 2
Binary True
Capabilities 
CapabilityDescriptions 
Caption Standard Serial over Bluetooth link (COM10)
ConfigManagerErrorCode 0
ConfigManagerUserConfig False
CreationClassName Win32_SerialPort
Description Standard Serial over Bluetooth link
DeviceID COM10
ErrorCleared 
ErrorDescription 
InstallDate 
LastErrorCode 
MaxBaudRate 9600
MaximumInputBufferSize 0
MaximumOutputBufferSize 0
MaxNumberControlled 
Name Standard Serial over Bluetooth link (COM10)
OSAutoDiscovered True
PNPDeviceID BTHENUM\{00001101-0000-1000-8000-00805F9B34FB}_LOCALMFG&0000\8&3062A492&0&000000000000_0000001C
PowerManagementCapabilities System.UInt16[]
PowerManagementSupported False
ProtocolSupported 
ProviderType RS232 Serial Port
SettableBaudRate True
SettableDataBits True
SettableFlowControl True
SettableParity True
SettableParityCheck False
SettableRLSD True
SettableStopBits True
Status OK
StatusInfo 3
Supports16BitMode False
SupportsDTRDSR True
SupportsElapsedTimeouts True
SupportsIntTimeouts True
SupportsParityCheck False
SupportsRLSD True
SupportsRTSCTS True
SupportsSpecialCharacters False
SupportsXOnXOff False
SupportsXOnXOffSet False
SystemCreationClassName Win32_ComputerSystem
SystemName JVALDRON-PC
TimeOfLastReset 
3

3 Answers

8
votes

You are unable to find this information out via the SerialPort class. You would need to do a WMI query.

Doing something along the lines of this may lead you to it

ManagementObjectSearcher searcher = new ManagementObjectSearcher("Select * 
                                      from WIN32_SerialPort");

foreach(ManagementObject Port in searcher.Get()) {

       string a = (string) Port.GetPropertyValue("Name");

}

I haven't got this code loaded so I don't know what further properties you can obtain. However if there was anyway, WMI would be the way to do it.

0
votes

I see your looking at a Bluetooth connected device:

Query the Win32_PnPSignedDriver and look at the InfName property. The value should be bthspp.inf

I cannot say with certainty that the inf file will ALWAYS be this name for every vendor's bluetooth device that supports SPP protocol, but this is the default.

Class GUID for COM & LPT ports is: {4d36e978-e325-11ce-bfc1-08002be10318} Ref: https://msdn.microsoft.com/en-us/library/windows/hardware/ff553426

ManagementObjectSearcher Searcher = new ManagementObjectSearcher( computer + @"root\cimv2", 
              "SELECT * FROM Win32_PnPSignedDriver " 
            + "WHERE    ClassGuid = '{4d36e978-e325-11ce-bfc1-08002be10318}' " 
            +       AND DeviceID LIKE 'BTHENUM%' 
            );
0
votes

Maybe this helps somebody. Code will return all available SPP Serialports.

public List<AvailableComPort> LoadAvailableComPorts()
    {
        List<AvailableComPort> serialComPortList = new List<AvailableComPort>();
        using (var searcher = new ManagementObjectSearcher("SELECT * FROM WIN32_SerialPort"))
        {
            foreach (ManagementObject queryObj in searcher.Get())
            {
                if (queryObj["PNPDeviceID"] != null && queryObj["DeviceID"] != null)
                {
                    //
                    // "BTHENUM\{00001101-0000-1000-8000-00805F9B34FB}_LOCALMFG&0002\7&1ADE6D9D&1&0012F328A5A3_C00000000"
                    // => get only "0012F328A5A3" as ID

                    string pnpDeviceId = queryObj["PNPDeviceID"].ToString();
                    string id = pnpDeviceId.Split(new string[] { "\\" }, StringSplitOptions.None).LastOrDefault();
                    id = id.Split(new string[] { "&" }, StringSplitOptions.None).LastOrDefault();
                    id = id.Split(new string[] { "_" }, StringSplitOptions.None).FirstOrDefault();

                    if (serialComPortList.Where(o => o.Id == id).Count() == 0)
                        serialComPortList.Add(new AvailableComPort() { Id = id, ComPort = queryObj["DeviceID"].ToString() });
                }
            }
        }

        List<AvailableComPort> comPortAdvancedList = new List<AvailableComPort>();
        using (ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity"))
        {
            foreach (ManagementObject queryObj in searcher.Get())
            {
                if (queryObj["PNPDeviceID"] != null && queryObj["Name"] != null)
                {
                    string pnpDeviceId = queryObj["PNPDeviceID"].ToString();
                    if (comPortAdvancedList.Where(o => o.Id == pnpDeviceId).Count() == 0)
                        comPortAdvancedList.Add(new AvailableComPort() { Id = pnpDeviceId, Name = queryObj["Name"].ToString() });
                }
            }
        }

        List<AvailableComPort> finalComPortList = new List<AvailableComPort>();
        foreach (var serialComPort in serialComPortList)
        {
            AvailableComPort comPortAdvanced = comPortAdvancedList.Where(o => o.Id.Contains("DEV_" + serialComPort.Id)).FirstOrDefault();
            if (comPortAdvanced != null)
            {
                comPortAdvanced.ComPort = serialComPort.ComPort;
                finalComPortList.Add(comPortAdvanced);
            }
        }
        return finalComPortList;
    }

public class AvailableComPort
{
    public string Id { get; set; }
    public string ComPort { get; set; }
    public string Name { get; set; }
}