List of SerialPorts queried using WMI differs from devicemanager?

扶醉桌前 提交于 2020-01-21 04:27:27

问题


I have the following serial ports listed in my devicemanager:

  • COM3
  • COM4 (BT)
  • COM5 (BT)
  • COM6 (GlobeTrotter MO67xx - Control Interface)
  • COM7 (GlobeTrotter MO67xx - GPS Control Interface)
  • COM8 (GlobeTrotter MO67xx - GPS Data Interface)
  • COM9 (GlobeTrotter MO67xx - Diagnostics Interface)
  • COM11 (USB Serial Port)
  • COM12 (USB Serial Port)
  • COM45 (SUNIX COM Port)
  • COM46 (SUNIX COM Port)

The SUNIX COM ports are connected via an internal PCI-Card. The USB Serial Port is connected via USB (FDTI-chip) The GlobeTrotter ports are from a GlobeTrotter device connected via USB. There are also a modem, a USB-device and a network device listed for this modem.

So I have several different sources of serial ports.

All I want to do is to get a list containing all those ports using WMI.

For my tests I am using WMI Code Creator

Test 1:

root\CIMV2; Query: SELECT * FROM Win32_SerialPort only returns the following serial ports:

  • COM3
  • COM4
  • COM5

Test 2:

root\WMI; Query: SELECT * FROM MSSerial_PortName only returns the following serial ports:

  • COM3
  • COM11
  • COM12
  • COM45
  • COM45

How can I get a complete list of serial ports?


回答1:


I found the solution.

The following query (root\CIMV2) gets the requested results:

SELECT * FROM Win32_PnPEntity WHERE ClassGuid="{4d36e978-e325-11ce-bfc1-08002be10318}"

Update

This answer is pretty old now. Ehen I asked it I still had to consider WinXP and was using Windows7. Since I don't deal with serial ports any more, I can't give any new information on that issue. At that time this solution reported all ports that the devicemanager was showing. But I know listing serial ports is not that easy so this answer might not be correct in all scenarios.




回答2:


In my case, I have physical serial ports, USB serial ports, and com0com virtual serial ports. I need both the full names, and COM port addresses.

The query suggested in this answer does not find com0com ports. The query suggested in this answer requires Administrator priviledges.

SELECT * FROM Win32_PnPEntity find all devices. It returns physical devices like this, and address can be parsed from Caption:

Serial Port for Barcode Scanner (COM13)

However, for com0com ports Caption is like this (no address):

com0com - serial port emulator

SELECT * FROM Win32_SerialPort returns addresses (DeviceID), as well as full names (Name). However, it only finds physical serial ports and com0com ports, not USB serial ports.

So in the end, I need two WMI calls: SELECT * FROM Win32_SerialPort (address is DeviceID) and SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%(COM%' (address can be parsed from Caption). I have narrowed down the Win32_PnPEntity call, because it only needs to find devices that were not found in the first call.




回答3:


The Win32_SerialPort class used in this article reports the physical com ports, if you wanna enumerate all the serial ports including the USB-Serial/COM ports, you must use the MSSerial_PortName class located in the root\wmi namespace.

Also try these classes located in the same namespace

  • MSSerial_CommInfo
  • MSSerial_CommProperties
  • MSSerial_HardwareConfiguration
  • MSSerial_PerformanceInformation

Note : If you want to know the properties and methods of this class you can use the WMI Delphi Code Creator.




回答4:


I had a similar issues trying to have an application locate the COM port for a USB Serial device.

By using the scope \\localhost\root\CIMV2 for the query SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode = 0, the application was able to find COM ports via each returned object's caption or locate the exact port by checking the caption for the device name.

ManagementObjectSearcher comPortSearcher = new ManagementObjectSearcher(@"\\localhost\root\CIMV2", "SELECT * FROM Win32_PnPEntity WHERE ConfigManagerErrorCode = 0");

        using (comPortSearcher)
        {
            string caption = null;
            foreach (ManagementObject obj in comPortSearcher.Get())
            {
                if (obj != null)
                {
                    object captionObj = obj["Caption"];
                    if (captionObj != null)
                    {
                        caption = captionObj.ToString();
                            if (caption.Contains("CH340"))
                            {
                                _currentSerialSettings.PortName = caption.Substring(caption.LastIndexOf("(COM")).Replace("(", string.Empty).Replace(")", string.Empty);
                            }
                    }
                }
            }
        }

The parsing code was found at [C#] How to programmatically find a COM port by friendly name



来源:https://stackoverflow.com/questions/19840811/list-of-serialports-queried-using-wmi-differs-from-devicemanager

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!