I have some legacy code that provides a list of the available COM ports on the PC by calling the EnumPorts() function and then filtering for the port names that start with \
In my case, I need both the full names, and COM port addresses. I have physical serial ports, USB serial ports, and com0com virtual serial ports.
Like the accepted answer suggests, I use WMI calls. 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.