Ist es möglich, mit MSCOMM32 die Liste der verfügbaren seriellen Ports
abzufragen? Ich denke da an die Funktion SerialPort.GetPortNames, die im
Dotnet vorhanden ist. Ein Kollege programmiert in VB6, wo es diese Funktion
anscheinend noch nicht gibt.
Note: Weder ich noch der Kollege haben tiefgreifend Ahnung von der Materie.
Es geht darum, alle vorhanden Ports nach einem Gerät abzufragen und bei
Vorhandensein mit diesem zu kommunizieren. Bisher muß der Port per Hand
ausgewählt werden, das sollte aber auch (für den Benutzer) einfacher gehen.
Die Frage ist halt wie.
Gruß
Falko
Hallo Rudolph,
Ich habe mir mal, nach dem Suchen im Web, folgende Routine zum Suchen
der COM-Schnittstellen "gebastelt". Für dich wäre wahrscheinlich die
Variable "Hilfe1" interessant, da hier die Portnamen eingelesen werden.
Wahrscheinlich musst du die Routine für dich aber noch weiter anpassen.
Gruß Wolfgang
Option Explicit
Option Compare Binary
'folgende API werden für Ermittlung der Com-Ports verwendet
Private Declare Function EnumPorts Lib "winspool.drv" Alias "EnumPortsA"
(ByVal pName As String, ByVal Level As Long, pPorts As Any, ByVal cbBuf
As Long, pcbNeeded As Long, pcReturned As Long) As Long
Private Declare Function lstrlen Lib "kernel32" Alias "lstrlenA" (ByVal
lpString As Any) As Long
Private Declare Function lstrcpy Lib "kernel32" Alias "lstrcpyA" (ByVal
lpString1 As Any, ByVal lpString2 As Any) As Long
Private Type PORT_INFO_2
pPortName As Long
pMonitorName As Long
pDescription As Long
fPortType As Long
reserved As Long
End Type
Public Function ComSuchen(ByRef ComPorts() As String) As Integer
Dim Retval As Long
Dim buffersize As Long
Dim CountPorts As Long
Dim I As Integer
Dim Ports() As PORT_INFO_2
Dim hilfe1 As String
Dim AnzahlSerPort As Integer
Dim J As Integer
Dim Swap As String
'Anzahl Ports ermitteln
'**** Achtung: Hier sollte noch geprüft werden, ob Comports() Array
auch tatsächlich dimmensioniert wurde!
Retval = EnumPorts(vbNullChar, 2, ByVal 0&, 0&, buffersize, CountPorts)
'Puffer erstellen und Portinfos ermitteln
ReDim Ports(buffersize / Len(Ports(0)) + 1)
Retval = EnumPorts(vbNullChar, 2, Ports(0), Len(Ports(0)) *
(UBound(Ports) + 1), buffersize, CountPorts)
'Namen jedes Ports ermitteln
If CountPorts > 0 Then
AnzahlSerPort = 0
For I = 0 To CountPorts - 1
'hier wird auf Com?: getestet
' falls nicht werden auch LPT und File aufgezeichnet
hilfe1 = PtrToString(Ports(I).pPortName)
debug.print hilfe1 'zum Testen
If Len(hilfe1) = 5 Then
If (Left$(hilfe1, 3) = "COM") And (Mid$(hilfe1, 5, 1) = ":") Then
ReDim Preserve ComPorts(AnzahlSerPort)
ComPorts(AnzahlSerPort) = Left$(hilfe1, 4)
AnzahlSerPort = AnzahlSerPort + 1
End If
End If
If Len(hilfe1) = 6 Then
If (Left$(hilfe1, 3) = "COM") And (Mid$(hilfe1, 6, 1) = ":") Then
ReDim Preserve ComPorts(AnzahlSerPort)
ComPorts(AnzahlSerPort) = Left$(hilfe1, 5)
AnzahlSerPort = AnzahlSerPort + 1
End If
End If
Next I
' ComPorts Sortieren
For I = 0 To UBound(ComPorts)
For J = I To UBound(ComPorts)
If ComPorts(I) > ComPorts(J) Then
Swap = ComPorts(I)
ComPorts(I) = ComPorts(J)
ComPorts(J) = Swap
End If
Next J
Next I
' Debug.Print "----------------------"
' For I = 0 To UBound(ComPorts)
' Debug.Print ComPorts(I)
' Next
End If
ComSuchen = AnzahlSerPort
End Function
'String anhand eines Pointers ermitteln
Private Function PtrToString(ByVal StringPtr As Long) As String
Dim TmpStr As String
TmpStr = Space$(lstrlen(StringPtr))
Call lstrcpy(TmpStr, StringPtr)
PtrToString = TmpStr
End Function
'Aufruf in Form:
Dim AnzahlComports As Integer
Dim COMVorhanden() As String
AnzahlComports = modComSuchen.ComSuchen(COMVorhanden) 'Gibt die
Anzahl der Comports zurück.
Grundsätzliches: Auf einem "Standard"-Win System können COM-Ports von COM1
bis COM256 existieren. (lassen wir mal die exotischen Treiberlösungen mit
COM-Ports bis zu COM4096 außen vor ;-)
Kennst Du "EnumSerialPorts" von Naughter? Ist zwar in C geschrieben, aber es
geht ja nur darum, welche Möglichkeiten/Funktionen Du hast um die verfügbaren
seriellen Ports zu ermitteln.
http://www.naughter.com/enumser.html
http://www.naughter.com/download/enumser.zip
Sage und schreibe 7 verschiedene Möglichkeiten listet dieses
Beispielprogramm auf.
Aus meiner Erfahrung sind die folgenden zuverlässig:
Methode 1: CreateFile()
Methode 2: QueryDosDevice()
Prinzip der Methode 1: Eine Schleife in der nacheinander COM1 bis COM256
geöffnet werden und die jeweiligen Rückgabewerte UND(!) GetLastError-Werte
ausgewertet werden.
Vorteil: Diese Methode ist bei der Porterkennung sehr zuverlässig (von Win95
bis WinVista/Server2008).
Nachteil: Mit jedem Öffnen eines tatsächlich vorhandenen COM-Ports werden
kurz die Leitungen umgeschaltet. Dies kann evtl. störend sein, je nachdem
welche Geräte am RS232-Port angeschlossen sind, z.B. Modems oder auch interne
virtuelle Geräte.
Prinzip der Methode 2: Im Buffer nach den Strings "COMxxx" suchen.
Vorteile: Diese Methode ist bei der Porterkennung zuverlässig (von WinNT bis
WinVista/Server2008). Und wesentlich schneller als mit der CreateFile-Methode!
Nachteile: Funktioniert nicht mit Win95/98/Me! Und wenn z.B. ein
USB-RS232-Konverter im aktiven Betrieb (also geöffnetem Port!) abgezogen
wird, dann verbleibt diese COM-Port-Nummer in der Liste, obwohl der Konverter
schon längst abgezogen ist!
Am besten, lade das Beispielprogramm herunter und guck Dir die Ergebnisse
der unterschiedlichen Methoden an.
Die anderen Methoden in Kurzform:
Methode 3 GetDefaultCommConfig: Scheint ähnlich zuverlässig zu sein wie
Methode 1. Diese verwende ich nicht, da ich mit den ersten beiden Methoden
sehr zufrieden bin.
Methode 4 SetupAPI (1): Erkennt keine COM-Ports von eingien internen Modems
(ist seltener als mit der nächsten Methode 5)
Methode 5 SetupAPI (2): Erkennt keine COM-Ports von internen Modems (z.B.
Laptops) oder USB-Modems.
Methode 6 EnumPorts: Zeigt grundsätzlich alle Ports an, die jemals verwendet
wurden (!) also auch nach einem Rechner-Neustart. Z.B. wenn Du mal einen USB-
oder PCMCIA-Port mal verwendet hast.
Methode 7 WMI: zeigt z.B. USB-RS232-Konverter gar nicht an (funktioniert
aber mit PCMCIA-Adaptern!)
Bei Fragen, hau einfach in die Tasten ;-)
Martin
Besten Dank schon mal für Eure detaillierten Antworten. Ich glaube, das
hilft meinem Kollegen weiter, zumindestens wirkte er sehr zuversichtlich.
Falko