문제

Windows 시스템에 사용 가능한 Serial (COM) 포트를 나열하는 강력한 방법을 찾고 있습니다. 거기 있습니다 WMI 사용에 대한이 게시물, 그러나 .NET별로 .NET이없는 .NET가없는 포트 목록이나 C ++ 프로그램에서 포트 목록을 가져오고 싶습니다.

나는 현재 다른 두 가지 접근법을 알고 있습니다.

  1. 정보를 읽습니다 HARDWARE\\DEVICEMAP\\SERIALCOMM 레지스트리 키. 이것은 훌륭한 옵션처럼 보이지만 건장한? 이 레지스트리 셀이 실제로 사용 가능한 포트의 전체 목록을 보유하고 있다는 온라인 또는 MSDN에서 보증을 찾을 수 없습니다.

  2. 전화를 시도하십시오 CreateFile ~에 COMN N 숫자로 1에서 무언가로. 일부 COM 포트의 이름이 COMN이 아니기 때문에 이것은 충분하지 않습니다. 예를 들어, 생성 된 일부 가상 COM 포트는 CSNA0, CSNB0 등 이므로이 방법에 의존하지 않습니다.

공유 할 다른 방법/아이디어/경험이 있습니까?

편집하다: 그건 그렇고, 여기에는 레지스트리에서 포트 이름을 읽는 간단한 파이썬 구현이 있습니다.

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
도움이 되었습니까?

해결책

몇 가지 옵션을 사용할 수 있습니다.

  1. 부르다 querydosdevice 모든 DOS 장치를 나열하는 NULL LPDEVICENAME를 사용합니다. 그런 다음 CreateFile을 사용하십시오 getCommConfig 각 장치 이름이 직렬 포트인지 알아 내기 위해 차례로.

  2. 부르다 SETUPDIGETCLASSDEVS guid_devinterface_comport의 클래스 가이드와 함께.

  3. C/C ++ 프로그램에서도 WMI를 사용할 수 있습니다..

대화에 약간의 대화가 있습니다 Win32 뉴스 그룹 그리고 Codeproject, er, 프로젝트.

다른 팁

파이썬과 함께 pyserial 사용 :

import serial.tools.list_ports


ports = list(serial.tools.list_ports.comports())
for p in ports:
    print p

pyserial 프로젝트는 a 몇 가지 해결책.

방금 C ++ 소스를 통해 읽는 것을 바탕으로 다음을 만들었습니다. 열거적인 포트 그리고 기능을보고 GetDefaultCommConfig(). 간단한 ANSI C와 가능한 각 COM 포트에 대해 단일 API 호출을 사용하는 가장 간단한 방법처럼 보였습니다.

#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;
}

이것은 확실히 상당히 늦었지만 나에게 도움이된다는 것이 입증되었습니다!

http://eli.thegreenplace.net/2009/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

pyserial 배포판에는 이제 scanwin32.py라는이를 수행하는 예가 있습니다.

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

WMI는 가기가 쉽고 코드가 최소화되어 있기 때문에 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)

내 생각에 당신의 직렬 포트는 일종의 플러그 플레이이기 때문에 이것이 제대로 작동해야합니다. 몇 가지 이유 Win32_SerialPort 모든 포트에서 작동하지 않습니다.

요즘에는 PowerShell One-Liner가 있습니다.

[System.IO.Ports.SerialPort]::GetPortNames()
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top