2

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?

  • Probably because this is a synchronous query. Same thing happens for USB mouting while querying `win32_LogicalDisk`. You likely need to switch to an asynchronous WQL query. http://msdn.microsoft.com/en-us/library/cc143292.aspx – David-SkyMesh Feb 14 '14 at 08:48
  • That was correct @David-SkyMesh. If you add that as an answer I'll accept it. And thank you for the direction, very helpful! – Matthew Hilgenfeld Feb 18 '14 at 22:02
  • @MatthewHilgenfeld Would you be able to provide the code you have that performs the asynchronous query and fixes the problem? – JacobD Dec 16 '14 at 10:18

2 Answers2

2

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#

Community
  • 1
  • 1
Synck
  • 2,727
  • 22
  • 20
  • Synck's answer implies this, but I want to make it more obvious: "Win32_SerialPort" doesn't always contain all serial ports (as you can see, when you follow the provided link) – frank koch Jan 27 '17 at 11:27
0

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.

David-SkyMesh
  • 5,041
  • 1
  • 31
  • 38
  • I would very much appreciate extra information regarding why semi-synchronous and synchronous requests are to blame here. Found this answer looking on how to enumerate COM ports with WMI, got worried. Googled for such info, found nothing. – Codeguard May 13 '15 at 08:51
  • 1
    @Codeguard I don't know why. I first encountered the problem when trying to implement a USB storage insertion/ejection/removal watcher for Firefox. http://stackoverflow.com/questions/21399770/jsctypes-problems-using-shchangenotifyregister-for-media-drive-events . It doesn't seem limited to USB storage and serial devices though. I've experienced the same thing again monitoring attachment of USB-based video capture devices. – David-SkyMesh May 13 '15 at 14:33