Список последовательных (COM) портов в Windows? - PullRequest
28 голосов
/ 30 июля 2009

Я ищу надежный способ перечисления доступных последовательных (COM) портов на компьютере с Windows. Есть этот пост об использовании WMI , но я бы хотел что-то менее специфичное для .NET - я хочу получить список портов в программе на Python или C ++ без .NET.

В настоящее время я знаю два других подхода:

  1. Чтение информации в разделе реестра HARDWARE\\DEVICEMAP\\SERIALCOMM. Это выглядит как отличный вариант, но действительно ли это надежный ? Я не могу найти онлайн или в MSDN гарантию, что эта ячейка реестра действительно всегда содержит полный список доступных портов.

  2. Попробуйте набрать CreateFile на COMN с N числом от 1 до чего-то. Это недостаточно хорошо, потому что некоторые COM-порты не называются COMN. Например, некоторые созданные виртуальные COM-порты называются CSNA0, CSNB0 и т. Д., Поэтому я бы не стал полагаться на этот метод.

Какие-нибудь другие методы / идеи / опыт, чтобы поделиться?

Редактировать: Кстати, вот простая реализация Python для чтения имен портов из реестра:

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

Ответы [ 8 ]

31 голосов
/ 28 августа 2014

Использование pySerial с Python:

import serial.tools.list_ports


ports = list(serial.tools.list_ports.comports())
for p in ports:
    print p
7 голосов
/ 30 июля 2009

Доступны несколько вариантов:

  1. Вызовите QueryDosDevice с пустым lpDeviceName, чтобы получить список всех устройств DOS. Затем используйте CreateFile и GetCommConfig с каждым именем устройства по очереди, чтобы определить, является ли это последовательный порт.

  2. Вызов SetupDiGetClassDevs с ClassGuid GUID_DEVINTERFACE_COMPORT.

  3. WMI также доступен для программ на C / C ++ .

В группе новостей win32 и CodeProject, project .

6 голосов
/ 11 июня 2010

Проект PySerial предоставляет пару решений .

5 голосов
/ 11 июня 2010

Я только что создал следующее, основываясь на чтении исходного кода C ++ до EnumSerialPorts и просмотре функции GetDefaultCommConfig(). Это выглядело как самый простой метод с использованием простого ANSI C и одного вызова API для каждого возможного COM-порта.

#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;
}
3 голосов
/ 05 июня 2013

Это определенно довольно поздно, но это оказалось полезным для меня!

http://eli.thegreenplace.net/2009/07/31/listing-all-serial-ports-on-windows-with-python/

В частности, этот пример:

import re

def full_port_name(portname):
    """ Given a port-name (of the form COM7,
        COM12, CNCA0, etc.) returns a full
        name suitable for opening with the
        Serial class.
    """
    m = re.match('^COM(\d+)$', portname)
    if m and int(m.group(1)) < 10:
    return portname
return '\\\\.\\' + portname
2 голосов
/ 08 августа 2015

В настоящее время для этого есть однострочник Powershell.

[System.IO.Ports.SerialPort]::GetPortNames()
2 голосов
/ 26 марта 2015

Я думаю, что WMI - это то, что нужно, так как его довольно легко запустить, и у него минимальный код. Это избавляет вас от необходимости копаться в реестре и дает некоторую гарантию того, что в будущем это сработает для более общих ситуаций.

Вы можете установить все необходимое с pip install pypiwin32 WMI, и оно работает "из коробки".

Код

import wmi

query = "SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%(COM%)'"
coms  = wmi.WMI().query(query)

for com in coms:
    print(com.Name)

Выход

Communications Port (COM1)
mbed Serial Port (COM3)
mbed Serial Port (COM5)

Я предполагаю, что ваш последовательный порт является своего рода Plug 'n Play, так что это должно работать нормально. По какой-то причине Win32_SerialPort работает не для всех портов.

2 голосов
/ 13 января 2012

В настоящее время в дистрибутиве pyserial есть такой пример, который называется scanwin32.py

http://pyserial.sourcearchive.com/documentation/2.5/scanwin32_8py_source.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...