programing

Windows에서 COM(시리얼) 포트를 나열하시겠습니까?

lastcode 2023. 10. 14. 10:17
반응형

Windows에서 COM(시리얼) 포트를 나열하시겠습니까?

Windows 컴퓨터에서 사용 가능한 COM(직렬) 포트를 나열하는 강력한 방법을 찾고 있습니다.WMI를 사용하는 것에 대한 게시물이 있지만, 조금 더 적은 것을 원합니다.NET 특정 - 없는 Python 또는 C++ 프로그램의 포트 목록을 가져오려고 합니다.그물.

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

  1. 의 정보를 읽습니다.HARDWARE\\DEVICEMAP\\SERIALCOMM레지스트리 키.이것은 좋은 선택처럼 보이지만, 견고합니까?이 레지스트리 셀이 항상 사용 가능한 포트의 전체 목록을 보유하고 있다는 보장을 온라인이나 MSDN에서 찾을 수 없습니다.

  2. 전화 시도CreateFile위에COMN1부터 어떤 것까지 N개의 숫자를 가지고 있습니다.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

Python과 함께 pySerial 사용하기:

import serial.tools.list_ports


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

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

  1. NULLlpDeviceName으로 QueryDosDevice를 호출하여 모든 DOS 디바이스를 나열합니다.그런 다음 각 장치 이름과 함께 CreateFile과 GetCommConfig를 차례로 사용하여 시리얼 포트인지 여부를 확인합니다.

  2. 클래스 가이드가 GUID_DEVINTERFATION_COMPORT인 SetupDiGetClassDevs를 호출합니다.

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

win32 뉴스 그룹과 코드 프로젝트에 대한 대화가 있습니다.

PySerial 프로젝트는 몇 가지 솔루션을 제공합니다.

저는 방금 EnumSerialPorts로 C++ 소스를 읽고 함수를 본 것을 바탕으로 다음을 만들었습니다.GetDefaultCommConfig(). 간단한 ANSIC와 가능한 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;
}

요즘에는 파워셸 원라이너가 있습니다.

[System.IO.Ports.SerialPort]::GetPortNames()

꽤 늦었지만 도움이 된다는 것이 증명되었답니다!

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

이제 scanwin32.py 이라고 하는 작업을 수행하는 예가 물리적 배포판에 있습니다.

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

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모든 포트에 대해 작동하지 않습니다.

언급URL : https://stackoverflow.com/questions/1205383/listing-serial-com-ports-on-windows

반응형