Question

Running the below code locks up my com port, and I would LOVE to know why. I have found a couple unanswered questions on SO that are similar...

I am using Bluetooth adapters (RN-41) to make a serial connection. The adapters SPP create two virtual com ports (This is common to all adapters we have tested). Windows labels them as Incoming and Outgoing, but the Incoming is the only one that actually carries serial data.

That leaves me with 'extra' virtual serial ports. I populate a dropdown with the available Com ports so the user can select the port to connect to from the list.

Prior to that, I am filtering that list to remove the 'fake' com ports. Here is my code:

public string checkBluetoothCom()
        {
            string bluetoothComm = "";
            List<string> badComPorts = new List<string>();
            ManagementClass processClass = new ManagementClass("WIN32_SerialPort");

            ManagementObjectCollection Ports = processClass.GetInstances();

            foreach (ManagementObject property in Ports)
            {
                if (property.GetPropertyValue("Name").ToString().Contains("Bluetooth"))
                {
                    string hardwareAddress = property.GetPropertyValue("PNPDeviceID").ToString().Split('&')[4].Split('_')[0];
                    if (!hardwareAddress.All(c => c == '0'))
                    {
                        bluetoothComm = property.GetPropertyValue("DeviceID").ToString();
                    }
                    else
                    {
                        badComPorts.Add(property.GetPropertyValue("DeviceID").ToString());
                    }
                }
            }

            Console.WriteLine("Removing {0} items from comm port list", badComPorts.Count);
            ports.RemoveAll(item => badComPorts.Contains(item));

            return bluetoothComm;
        }

The problem is that after this runs my Com Port locks up and I cannnot make any connection until I remove my bluetooth adapter and restart the remote device (RN-41). Any thoughts?

Was it helpful?

Solution 2

For certain resource types (typically physical ports), using "synchronous" (or even "semi-synchronous") WQL queries can interrupt (or even cause denial of service on) the services managing those resources.

An example is that if you query win32_LogicalDisk while inserting a USB flash storage device, it can fail to mount as a logical volume.

You probably need to make an an "asynchronous" query.

Reference: How to perform Asynchronous WMI WQL queries. (C#)

There are two varieties of "asynchronous" WQL query consumers: "temporary" and "permanent".

"Temporary" consumers are programs where you just run a polling loop, sending an "asynchronous" WQL query with some timeout (say 2 seconds). If nothing occurs within the timeout, the query returns an empty result-set, and you restart the loop (send another query).

"Permanent" consumers are registered with the WMI services themselves. PowerEvents for Windows Powershell is a good example of tooling in this area.

OTHER TIPS

If you query "Win32_PnPEntity" instead of "Win32_SerialPort" and check for the COM port ClassGuid {4d36e978-e325-11ce-bfc1-08002be10318}, the port isn't locked up or accessed.

PowerShell example:

Get-WmiObject -Query "SELECT Name,DeviceID FROM Win32_PnPEntity WHERE ClassGuid=`"{4d36e978-e325-11ce-bfc1-08002be10318}`""

This gives a list of all the COM ports as can be found in the device manager.

Source: Finding information about all serial devices connected through USB in C#

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top