Listing serial (COM) ports on Windows?
Solution 1
Several options are available:
Call QueryDosDevice with a NULL lpDeviceName to list all DOS devices. Then use CreateFile and GetCommConfig with each device name in turn to figure out whether it's a serial port.
Call SetupDiGetClassDevs with a ClassGuid of GUID_DEVINTERFACE_COMPORT.
There's some conversation on the win32 newsgroup and a CodeProject, er, project.
Solution 2
Using pySerial with Python:
import serial.tools.list_ports
ports = list(serial.tools.list_ports.comports())
for p in ports:
print p
Solution 3
The PySerial project provides a couple of solutions.
Solution 4
I just created the following, based on reading through the C++ source to EnumSerialPorts and seeing the function GetDefaultCommConfig()
. It looked like the simplest method using simple ANSI C and a single API call for each possible COM port.
#include <stdio.h>
#include <windows.h>
#include <winbase.h>
BOOL COM_exists( int port)
{
char buffer[7];
COMMCONFIG CommConfig;
DWORD size;
if (! (1 <= port && port <= 255))
{
return FALSE;
}
snprintf( buffer, sizeof buffer, "COM%d", port);
size = sizeof CommConfig;
// COM port exists if GetDefaultCommConfig returns TRUE
// or changes <size> to indicate COMMCONFIG buffer too small.
return (GetDefaultCommConfig( buffer, &CommConfig, &size)
|| size > sizeof CommConfig);
}
int main()
{
int i;
for (i = 1; i < 256; ++i)
{
if (COM_exists( i))
{
printf( "COM%d exists\n", i);
}
}
return 0;
}
Solution 5
Nowadays there's a Powershell one-liner for that.
[System.IO.Ports.SerialPort]::GetPortNames()
Comments
-
Eli Bendersky almost 2 years
I'm looking for a robust way to list the available serial (COM) ports on a Windows machine. There's this post about using WMI, but I would like something less .NET specific - I want to get the list of ports in a Python or a C++ program, without .NET.
I currently know of two other approaches:
Reading the information in the
HARDWARE\\DEVICEMAP\\SERIALCOMM
registry key. This looks like a great option, but is it robust? I can't find a guarantee online or in MSDN that this registry cell indeed always holds the full list of available ports.Tryint to call
CreateFile
onCOMN
with N a number from 1 to something. This isn't good enough, because some COM ports aren't named COMN. For example, some virtual COM ports created are named CSNA0, CSNB0, and so on, so I wouldn't rely on this method.
Any other methods/ideas/experience to share?
Edit: by the way, here's a simple Python implementation of reading the port names from registry:
import _winreg as winreg import itertools def enumerate_serial_ports(): """ Uses the Win32 registry to return a iterator of serial (COM) ports existing on this computer. """ path = 'HARDWARE\\DEVICEMAP\\SERIALCOMM' try: key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, path) except WindowsError: raise IterationError for i in itertools.count(): try: val = winreg.EnumValue(key, i) yield (str(val[1]), str(val[0])) except EnvironmentError: break