AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi Auflistung aller 'verfügbaren' Comports
Thema durchsuchen
Ansicht
Themen-Optionen

Auflistung aller 'verfügbaren' Comports

Ein Thema von DelphiManiac · begonnen am 7. Feb 2007 · letzter Beitrag vom 8. Feb 2007
Antwort Antwort
Seite 1 von 2  1 2      
DelphiManiac

Registriert seit: 5. Dez 2005
742 Beiträge
 
#1

Auflistung aller 'verfügbaren' Comports

  Alt 7. Feb 2007, 15:37
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:
var
 ComPorts:TStringList;
begin
..
Comports:=TStringList.Create;
EnumComPorts(Comports); // Gibt mir die vorhandenen Comports zurück
..
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.
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:

procedure 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;
Vielen Dank
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#2

Re: Auflistung aller 'verfügbaren' Comports

  Alt 7. Feb 2007, 15:52
Zitat von DelphiManiac:
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.
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.
Hi,
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
  Mit Zitat antworten Zitat
DelphiManiac

Registriert seit: 5. Dez 2005
742 Beiträge
 
#3

Re: Auflistung aller 'verfügbaren' Comports

  Alt 7. Feb 2007, 16:53
@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:
  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;
Ich denke so kann man es machen, oder?
Gruß
DelphiManiac
  Mit Zitat antworten Zitat
7. Feb 2007, 20:11
Dieses Thema wurde von "sakura" von "Object-Pascal / Delphi-Language" nach "Windows API / MS.NET Framework API" verschoben.
Reinhard Kern

Registriert seit: 22. Okt 2006
772 Beiträge
 
#5

Re: Auflistung aller 'verfügbaren' Comports

  Alt 8. Feb 2007, 01:01
Zitat von DelphiManiac:
...
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 denke so kann man es machen, oder?
Gruß
DelphiManiac
Hallo,

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
  Mit Zitat antworten Zitat
DelphiManiac

Registriert seit: 5. Dez 2005
742 Beiträge
 
#6

Re: Auflistung aller 'verfügbaren' Comports

  Alt 8. Feb 2007, 12:19
@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
  Mit Zitat antworten Zitat
DelphiManiac

Registriert seit: 5. Dez 2005
742 Beiträge
 
#7

Re: Auflistung aller 'verfügbaren' Comports

  Alt 8. Feb 2007, 12:22
@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
  Mit Zitat antworten Zitat
Robert Marquardt
(Gast)

n/a Beiträge
 
#8

Re: Auflistung aller 'verfügbaren' Comports

  Alt 8. Feb 2007, 12:43
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.
  Mit Zitat antworten Zitat
Gehstock

Registriert seit: 28. Jan 2006
Ort: Görlitz / Sachsen
489 Beiträge
 
Delphi 2007 Professional
 
#9

Re: Auflistung aller 'verfügbaren' Comports

  Alt 8. Feb 2007, 13:53
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;
Marcel
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#10

Re: Auflistung aller 'verfügbaren' Comports

  Alt 8. Feb 2007, 14:10
Zitat von DelphiManiac:
Ich filtere die Liste und gucke ob die API darauf zugreifen kann, wenn nicht, dann entferne ich den Por aus der Liste.
  for I := 0 to _PList.Count - 1 do // Stringlist mit zB.['COM1','COM3',...]
Würde schon gehen; nur musst du die Liste zum Löschen rückwärts durchlaufen, da sich beim Löschen auch die Indizies ändern.
Andreas
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:50 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz