2009-07-30 16 views
25

Szukam solidnego sposobu na listę dostępnych portów szeregowych (COM) na komputerze z systemem Windows. Jest this post about using WMI, ale chciałbym coś mniej .NET specyficzne - Chcę uzyskać listę portów w programie Python lub C++, bez .NET.Wyświetlanie portów szeregowych (COM) w systemie Windows?

Obecnie wiadomo o dwóch innych metod:

  1. Odczytywanie informacji w kluczu HARDWARE\\DEVICEMAP\\SERIALCOMM rejestru. To wygląda na doskonałą opcję, ale czy jest to solidna? Nie mogę znaleźć gwarancji online lub w MSDN, że ta komórka rejestru rzeczywiście zawsze posiada pełną listę dostępnych portów.

  2. Tryint wywoływania CreateFile na COMN z N liczbą od 1 do czegoś. To nie jest wystarczająco dobre, ponieważ niektóre porty COM nie mają nazwy COMN. Na przykład niektóre wirtualne porty COM są nazywane CSNA0, CSNB0 itd., Więc nie będę polegać na tej metodzie.

Jakieś inne metody/pomysły/doświadczenia do udostępnienia?

Edit: przy okazji, oto prosta implementacja Pythona czytania nazwy portów z rejestru: Dostępne są

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 
+0

Świetnie! Działa bardzo dobrze. – luc

+0

Wygląda bardzo przydatny do znalezienia portów COM - spróbuję użyć go do znalezienia portu Arduino – SimpleSi

Odpowiedz

7

kilka opcji:

  1. połączeń QueryDosDevice z NULL lpDeviceName aby wyświetlić listę wszystkich urządzeń DOS. Następnie użyj CreateFile i GetCommConfig z każdą nazwą urządzenia, aby dowiedzieć się, czy jest to port szeregowy.

  2. Zadzwoń pod SetupDiGetClassDevs z ClassGuid z GUID_DEVINTERFACE_COMPORT.

  3. WMI is also available to C/C++ programs.

Jest jakaś rozmowa na win32 newsgroup i CodeProject eee project.

+0

Próbuję użyć QueryDosDevice, ale mam problem z tym, które urządzenia są portami szeregowymi. GetCommConfig nie jest częścią Pywin32 z jakiegoś powodu. –

+2

Byłem pod wrażeniem tego, jak dobrze [Teraterm] (http://logmett.com/index.php?/products/teraterm.html) wymienia port szeregowy. Sprawdziłem kod źródłowy i okazało się, że 'ListupSerialPort()' w ['ttcmn.c'] (http://en.sourceforge.jp/projects/ttssh2/svn/view/trunk/teraterm/ttpcmn/ ttcmn.c? view = markup & root = ttssh2) odnosi się do [tego projektu CodeProject] (http://www.codeproject.com/Articles/2609/Enumerating-serial-ports-W2K-style). –

5

Właśnie utworzyłem następujące, oparte na czytaniu przez źródło C++ do EnumSerialPorts i widząc funkcję GetDefaultCommConfig(). Wyglądało to jak najprostsza metoda przy użyciu prostego ANSI C i pojedynczego wywołania API dla każdego możliwego portu 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

Jest to z pewnością dość późno, ale okazało się pomocne dla mnie!

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

Szczególnie ten przykład:

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 
+14

Dzięki za skierowanie mnie na mój blog :-) !! –

+0

Yikes! Mały świat! ... to było głupie ze mnie. – eatonphil

+0

Bez obaw, fajnie było zobaczyć :-) –

28

Korzystanie pyserial z Python:

import serial.tools.list_ports 


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

Doskonale, dzięki. –

+0

Lub bezpośrednio z wiersza poleceń, 'python -m serial.tools.list_ports' –

2

myślę WMI jest droga, ponieważ jest to dość łatwo dostać się dzieje i ma minimalny kod. Oszczędza to konieczności kopania w rejestrze i daje gwarancję, że będzie działać w bardziej ogólnych sytuacjach w przyszłości.

Można zainstalować wszystko, co jest potrzebne z pip install pypiwin32 WMI i działa natychmiast po uruchomieniu.

Kod

import wmi 

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

for com in coms: 
    print(com.Name) 

Wyjście

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

Domyślam się, że port szeregowy jest jakaś Plug „n Play tak to powinno działać dobrze. Z jakiegoś powodu Win32_SerialPort nie działa dla wszystkich portów.

2

W dzisiejszych czasach istnieje jedno opakowanie liniowe.

[System.IO.Ports.SerialPort]::GetPortNames() 
Powiązane problemy