问题
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