![]() |
Auflistung aller 'verfügbaren' Comports
Hallo,
ich habe folgendes Problem, ich nutzte die Komonente TComport aus dem Package bzw der Unit CPort. Das ist eine Komponente die den Zugriff auf die Comports kapselt. Es gibt hier eine Funktion die sich EnumComPorts nennt, ihr übergibt man eine Stringlist und bekommt sie gefüllt mit den im System vorhandenen Comports zurück. Beispiel:
Delphi-Quellcode:
Das ist ja auch super, nur wenn ich mir jetzt die Comports in eine Auswahl a la Combobox oder Listbox lade habe ich folgendes Prob.
var
ComPorts:TStringList; begin .. Comports:=TStringList.Create; EnumComPorts(Comports); // Gibt mir die vorhandenen Comports zurück .. Es werden anscheinend alle Comports (die das System in der Registry hat) angezeigt, auch die die vielleicht schon durch ein anderes Programm in Benutztung sind (sehr unschön). Denn was bringt mir COM1 wenn sie belegt ist. Ich wollte euch fragen, wie die Ports am Besten rausfiltern kann. Bzw. ob ich eine andere Methode dafür nutzte. hier der Funktion EnumComports
Delphi-Quellcode:
Vielen Dankprocedure EnumComPorts(Ports: TStrings); var KeyHandle: HKEY; ErrCode, Index: Integer; ValueName, Data: string; ValueLen, DataLen, ValueType: DWORD; TmpPorts: TStringList; begin ErrCode := RegOpenKeyEx( HKEY_LOCAL_MACHINE, 'HARDWARE\DEVICEMAP\SERIALCOMM', 0, KEY_READ, KeyHandle); if ErrCode <> ERROR_SUCCESS then raise EComPort.Create(CError_RegError, ErrCode); TmpPorts := TStringList.Create; try Index := 0; repeat ValueLen := 256; DataLen := 256; SetLength(ValueName, ValueLen); SetLength(Data, DataLen); ErrCode := RegEnumValue( KeyHandle, Index, PChar(ValueName), {$IFDEF DELPHI_4_OR_HIGHER} Cardinal(ValueLen), {$ELSE} ValueLen, {$ENDIF} nil, @ValueType, PByte(PChar(Data)), @DataLen); if ErrCode = ERROR_SUCCESS then begin SetLength(Data, DataLen - 1); TmpPorts.Add(Data); Inc(Index); end else if ErrCode <> ERROR_NO_MORE_ITEMS then raise EComPort.Create(CError_RegError, ErrCode); until (ErrCode <> ERROR_SUCCESS) ; TmpPorts.Sort; Ports.Assign(TmpPorts); finally RegCloseKey(KeyHandle); TmpPorts.Free; end; end; |
Re: Auflistung aller 'verfügbaren' Comports
Zitat:
also an sich möchte ich hier (wieder?) die TComPort-Komponente pushen und sagen, dass das ja eigentlich genau das ist, was ich auch erwarten würde. Die listet alle vorhandenen Ports auf. Natürlich kannst Du schauen ob ein Port schon belegt ist (versuche den einfach zu öffnen, während jmd. anderes das getan hat), aber das schützt Dich auch nur bedingt. Hängt an COM1 ein Gerät das angeschaltet ist, aber dessen Software noch nicht gestartet wurde, so hast Du auch das Problem, dass COM1 als "frei" erkannt werden würde. Wie gesagt, das einfache Filtern kannst Du ohne Probleme durchführen indem Du einfach jeden Port den Du findest öffnest. Klappt das ohne Probleme ist der nicht in Verwendung. Hast Du ein Identifikations-Kommando zur Verfügung, so kannst Du natürlich so auch gleich automatisch alle Geräte ermitteln, die Du anbieten möchtest. Der Weg dürfte dann auch klar sein, Du versuchst einfach alle Ports zu öffnen und sendest auf jedem dieses Kommando, kommt eine (erwartete) Antwort, wird das richtige dranhängen. Der Weg ist allerdings riskanter, da Du natürlich nicht weißt was dein Kommando bei fremden Geräten auslöst. Zudem kommt dann das Problem der Unterscheidung zweier Baugleicher Geräte hinzu. Gruß Der Unwissende |
Re: Auflistung aller 'verfügbaren' Comports
@Der_Unwissende:
Hi lange nix voneinander gehört mich interessieren hierbei nur die Comports, die die Windows API auch wirklich öffnen kann. D.h. es kann ja noch eine virtuelle Comport Leiche in der Registry stehen z.B.: Com10, diese aber gar nicht mehr im System ist (USB auf RS232 ist ausgesteckt), dann wäre es nicht sinvoll diese anzuzeigen. Bzw. wenn ein Programm die Schnittstelle belegt, dann brauch diese auch nicht in meiner Liste. Ich habe es jetzt so gelöst: Ich filtere die Liste und gucke ob die API darauf zugreifen kann, wenn nicht, dann entferne ich den Por aus der Liste.
Delphi-Quellcode:
Ich denke so kann man es machen, oder?
for I := 0 to _PList.Count - 1 do // Stringlist mit zB.['COM1','COM3',...]
begin hPort := CreateFile( PChar( _PList.Strings[i] ), GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0, 0 ); if ( hPort = INVALID_HANDLE_VALUE ) then _PList.Delete(i); CloseHandle( hPort ); end; Gruß DelphiManiac |
DP-Maintenance
Dieses Thema wurde von "sakura" von "Object-Pascal / Delphi-Language" nach "Windows API / MS.NET Framework API" verschoben.
|
Re: Auflistung aller 'verfügbaren' Comports
Zitat:
ich habe an meinem Entwicklungssystem verschiedene Programmiergeräte, z.B. von Microchip an COM1. COM1 ist aber frei, wenn die Entwicklungsumgebung von Microchip nicht läuft, und selbst wenn sie läuft, belegt sie COM1 nur, wenn ich im Menu "Programmer Enable" wähle. Das gilt in ähnlicher Form für alle Programme, die COM-Ports benutzen, einschliesslich meiner eigenen. Es gibt daher praktisch keine Möglichkeit festzustellen, ob ein COM-Port "benutzt" wird, nicht einmal wenn man alle auf dem Rechner installierten Programme starten würde. Gruss Reinhard |
Re: Auflistung aller 'verfügbaren' Comports
@Reinhard Kern:
Hallo, ja aber wenn ich versuche über CreateFile den Port zu öffnen und dieses nicht klappt, Beispiel weil, bei mir ein In Circuit Debugger am Port hängt, der den Port für sich reserviert (geöffnet) hat, dann kann ich diesen Port(der ja aktuell nicht zurverfügung steht) aus meiner Schnittstellenauswahl löschen. Gruß DelphiManiac |
Re: Auflistung aller 'verfügbaren' Comports
@Der_Unwissende
Hallo, ja ich verstehe deine Idee, aber mein anliegen hier ist viel einfacher, ich will ja nicht wissen ob am Port das dranhängt was ich vermute (irgendein Gerät mit dem ich kommunizieren will) sondern, ich interessiere mich in erster Linie nur für die vorhandenen Ports, die ich auch bedienen (also öffnen) kann. Geht dieses nicht, so macht es auch an der Stelle keinen Sinn diesen Port aufzuführen. Gruß DelphiManiac |
Re: Auflistung aller 'verfügbaren' Comports
Da hilft nur der Versuch den COM-Port mit CreateFile und exklusivem Zugriff probeweise zu oeffnen.
Leichen von virtuellen COM-Ports sollte es eigentlich nicht geben. |
Re: Auflistung aller 'verfügbaren' Comports
Ich mach dat so
Delphi-Quellcode:
var
i:integer; begin ComPort.Items.Clear; //combobox for I := 1 to 30 do begin iComNum := I; if OpenCom(False) then begin ComPort.Items.Add(Format('COM%d',[I])); CloseCom; end; Application.ProcessMessages; end; // for ComPort.ItemIndex := ComPort.Items.Count-1; end;
Delphi-Quellcode:
function OpenCom(Mode:boolean) : boolean;
var dw : dword; begin result:=FALSE; if hCom<>INVALID_HANDLE_VALUE then CloseCom; if FlgOvrlp then dw:=FILE_FLAG_OVERLAPPED else dw:=FILE_ATTRIBUTE_NORMAL; hCom:=CreateFile(PChar('\\?\COM'+IntToStr(iComNum)),GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,dw,0); if hCom<>INVALID_HANDLE_VALUE then begin SetupComm(hCom,$20000,$20000); //8192, 8192); // Rd , Wr if GetComDCB then begin if Mode then DCB.Flags := (DCB.Flags and $ffff8000) or $0001 else DCB.Flags := (DCB.Flags and $ffff8000) or $0011; //$1011; DCB.ByteSize := 8; DCB.Parity := 0; DCB.StopBits := 0; DCB.BaudRate := iComBaud; if SetComDCB then begin ComTimeouts.ReadIntervalTimeout:=20; //0 ComTimeouts.ReadTotalTimeoutMultiplier:=1; //0 ComTimeouts.ReadTotalTimeoutConstant:=200; //200 ComTimeouts.WriteTotalTimeoutMultiplier:=0;//MAXDWORD; ComTimeouts.WriteTotalTimeoutConstant:=0;//MAXDWORD; if SetComTimeouts then begin iOldComOpen:=iComNum; iOldComBaud:=iComBaud; if Mode then begin sleep(75); EscapeComFunction(SETRTS); sleep(25); EscapeComFunction(SETDTR); end else begin sleep(75); EscapeComFunction(SETRTS); end; // sleep(300); // PurgeCom(PURGE_TXCLEAR or PURGE_RXCLEAR); result := TRUE; end; end; end; end; end; |
Re: Auflistung aller 'verfügbaren' Comports
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:16 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz