AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

COM Ports im System auslesen

Ein Thema von Moony · begonnen am 11. Aug 2008 · letzter Beitrag vom 12. Mär 2020
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.803 Beiträge
 
Delphi 12 Athens
 
#1

AW: COM Ports im System auslesen

  Alt 9. Mär 2020, 12:08
CreateFile bietet nur einen rudimentären Zugriff.
Für den volständigen Zugriff gibt es spezielle APIs.
https://docs.microsoft.com/de-de/win...ions-functions

Im neuen Delphi kannst dir über Get-It eine/mehrere SerialPort-Komponenten runterladen.
Eventuell hat Eine bereits ein entsprechendes Event für neue/getrennte Ports.
Oder halt manuell irgendwo suchen und installieren. Bei Google suchenDelphi AsyncPro Bei Google suchendelphi serial port)




Das Erkennen von Ports geht recht einfach, wobei CreateFile mit deiner halben Fehlerbehandlung nur "freie" Ports erkennt.

Das Abziehen des Serial-Controllers, wenn du grade eine Verbindung hast, ist einfach, da du hier eine Fehlermeldung bekommst. (Rückgabewerte deiner API-Aufrufe ala Read/Write/...)
Über die SetupAPI gibt es bestimmt direkte Events/Notifications.
Eventuell kommt auch ein WM_WININICHANGE im System rum, wenn ein Port hinzugefügt/entfernt wird.
Falls ich dran denk, kann ich heut abend mal nachsehn, was passiert, wenn ich einen Arduino an-/absteck.


Bleibt der USB-Serial-Wandler am System, dann ist es erstmal unmöglich überhaupt zu erkennen, ob am Seriel überhaupt was dran hängt,
da du bestimmt standardmäßig ohne Flusskontrolle arbeitest und somit das System es garnicht erkennen kann.
Hartwareflusssteuerung ala RTS/CTS wird vermutlich nicht aktiv sein. (ist es fast nie, da zu oft nur die beiden Datenleitungen verbunden sind, oder sogar nur eine Datenleitung)
Rückkopplung über Softwareprotokoll ist für das System nicht erkennbar, also ob die Software z.B. auf ein ACK-Signal oder X-ON/X-OFF reagiert.

USB-Serial im Board des AVR/Arduino/... (also USB-Port auf dem Board)
oder USB-Serial-Wandler immer komplett vom System abziehen,
nur das kann Windows etwas erkennen und dir mitteilen.

Bleibt der USB-Ports im System, dann kannst du nur pollen,
also regelmäßig dem ARV etwas schicken und auf eine Antwort warten ... kommt nichts zurück, dann ist er weg/aus.





Varianten zum Auflisten:

MSDN-Library durchsuchenGetDefaultCommConfig, bzw. die SetupAPI benutzen,
oder MSDN-Library durchsuchenQueryDosDevice und alles nehmen, was mit "COM" beginnt
oder siehe HKLM\Hardware\DeviceMap\SerialComm
oder WMI
oder ...

Bei CreateFile für Ports über 10 solltest/musst du den UNC-Pfad benutzen (bei kleiner muß nicht)
und da du nur auf freie Ports zugreifen kannst, die von keinem Programm aktuell im Zugriff sind, mußt du hier die Fehlerbehandluing "richtig" machen.
Also nicht nur das Result, sondern bei Fehler auch GetLastError auf "Zugriff verweigert" ausweten.

https://docs.microsoft.com/en-us/win...stall/setupapi

Da in der mitte findest du einen Beispielcode von Yangghi Min.
Und fast am Ende für QueryDosDevice.
https://social.msdn.microsoft.com/Fo...orum=vcgeneral

https://stackoverflow.com/questions/...ports-in-win32

https://stackoverflow.com/questions/...-devicemanager




Mit Delphi 6 jetzt erst angefangen?
Tipp: https://www.embarcadero.com/de/products/delphi/starter (ist sehr viel größer und wesentlich langsamer, kann aber auch mehr un)
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu ( 9. Mär 2020 um 12:24 Uhr)
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.257 Beiträge
 
Delphi 12 Athens
 
#2

AW: COM Ports im System auslesen

  Alt 9. Mär 2020, 12:27
Damit hat es mal gut funktioniert, habe ich aber unter Win10 nicht weiter getestet:

Delphi-Quellcode:
procedure TSerialManager.WinProc(Message, wParam, lParam : longint);
type
  TDev_Broadcast_Hdr = packed record
    dbch_size,
    dbch_devicetype,
    dbch_reserved : cardinal;
  end;
  PDev_Broadcast_Hdr = ^TDev_Broadcast_Hdr;
begin

  if Message=WM_DEVICECHANGE then
  begin
    if wParam=DBT_DEVICEARRIVAL then
    begin // Ein Gerät wurde hinzugefügt
      if PDev_Broadcast_Hdr(lParam).dbch_devicetype=DBT_DEVTYP_PORT then
      begin
....
      end;
    end
    else
    if wParam=DBT_DEVICEREMOVECOMPLETE then
    begin // Ein Gerät wurde entfernt
      if PDev_Broadcast_Hdr(lParam).dbch_devicetype=DBT_DEVTYP_PORT then
      begin
....
      end;
    end;
...
  end;
end;
  Mit Zitat antworten Zitat
1967Schorsch

Registriert seit: 28. Feb 2020
Ort: Dinslaken
8 Beiträge
 
Delphi 6 Enterprise
 
#3

AW: COM Ports im System auslesen

  Alt 9. Mär 2020, 20:38
Hallo zusammen,
für die Problematik fehlt es mir wohl an Fachwissen.

Das Beispiel von Rollo62 möchte ich gerne ausprobieren.... es schein aber die Komponenten TSerialmanager im Delphi 6 zu fehlen.

Ohne tiefgreifende Hilfe schaffe ich das nicht.

procedure TSerialManager.WinProc(Message, wParam, lParam : longint);
type
TDev_Broadcast_Hdr = packed record
dbch_size,
dbch_devicetype,
dbch_reserved : cardinal;
end;
PDev_Broadcast_Hdr = ^TDev_Broadcast_Hdr;
begin

if Message=WM_DEVICECHANGE then
begin
if wParam=DBT_DEVICEARRIVAL then
begin // Ein Gerät wurde hinzugefügt
if PDev_Broadcast_Hdr(lParam).dbch_devicetype=DBT_DEV TYP_PORT then
begin
....
end;
end
else
if wParam=DBT_DEVICEREMOVECOMPLETE then
begin // Ein Gerät wurde entfernt
if PDev_Broadcast_Hdr(lParam).dbch_devicetype=DBT_DEV TYP_PORT then
begin
....
end;
end;
...
end;
end;
Georg
  Mit Zitat antworten Zitat
TurboMagic

Registriert seit: 28. Feb 2016
Ort: Nordost Baden-Württemberg
3.108 Beiträge
 
Delphi 12 Athens
 
#4

AW: COM Ports im System auslesen

  Alt 9. Mär 2020, 22:36
Hallo,

eine solche Komponente brauchst du dafür gar nicht.
Platziere eine TApplicationEvents Komponente (gibt's hoffentlich in D6 schon)
auf deiner Form und schaue dir mal die Events dieser an. Die sollte ein vergleichbares
bieten wie Rollo62 es benutzt hat.

Dort dann mal den Inhalt seiner WinProc Methode einfügen.

Grüße
TurboMagic
  Mit Zitat antworten Zitat
Rollo62

Registriert seit: 15. Mär 2007
4.257 Beiträge
 
Delphi 12 Athens
 
#5

AW: COM Ports im System auslesen

  Alt 10. Mär 2020, 08:36
Das ist eine eigene Klasse, in der ich das gekapselt habe.
Ich hatte ja geschrieben das dort auch noch mehr drumrum zur Absicherung ist.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.803 Beiträge
 
Delphi 12 Athens
 
#6

AW: COM Ports im System auslesen

  Alt 10. Mär 2020, 11:38
Vermutlich musst du vorher dein Programm noch registieren, damit was ankommt.
https://docs.microsoft.com/en-us/win...enotificationa


und deine Codes bitte in [DELPHI]...[/DELPHI] oder [CODE]...[/CODE]
Ein Therapeut entspricht 1024 Gigapeut.
  Mit Zitat antworten Zitat
1967Schorsch

Registriert seit: 28. Feb 2020
Ort: Dinslaken
8 Beiträge
 
Delphi 6 Enterprise
 
#7

AW: COM Ports im System auslesen

  Alt 10. Mär 2020, 16:59
Ich habs dann irgendwie geschafft ein ApplicationEvents per Komponente einzufügen (Anfängerglück ).
In den Events sehe ich jetzt nicht was so ähnlich heißt wie seine TSerialManager.WinProc Prozedur.

Angehängte Grafiken
Dateityp: jpg ApplicationEvents.jpg (81,2 KB, 23x aufgerufen)
Georg
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.803 Beiträge
 
Delphi 12 Athens
 
#8

AW: COM Ports im System auslesen

  Alt 10. Mär 2020, 17:24
Application.OnMessage (Unit Forms) oder besser TApplicationEvents.OnMessage, weil es das mehrfach geben kann und man sich nicht selbst überschreibt.

Dort kommt alles vorbei, was via MSDN-Library durchsuchenPostMessage und MSDN-Library durchsuchenPostThreadMessage im Hauptthread des Programms eintrudelt,
und durch Application.Run bzw. Application.ProcessMessages/HandleMessage durchrauscht. (die Hauptbearbeitungsstellen der MessageQueue für unsere VCL)

Probleme gibt es nur, wenn jemand/etwas MSDN-Library durchsuchenPeekMessage/MSDN-Library durchsuchenGetMessage manuell aufruft und es nicht über Application.ProcessMessages oder .HandleMessage behandeln lässt, welche das OnMessage aufrufen.
z.B. in einigen Implementationen von Delay, als Nichthängenbleibender Ersatz des Sleep oder während ein Windows-Dialog ala MSDN-Library durchsuchenMessageBox angezeigt wird.

Diese Messages dürften via PostMessage als Broadcast im System verteilt werden
und standardmäßig nur an TopLevel-Fenster, wie z.B. die Hauptform oder das unsichtbare ControlWindow in Forms.Application.

Wie gesagt, MSDN-Library durchsuchenSendMessage kommt in dem Event blöder Weise nicht vorbei, dafür müsste man sich einen GetMessage-Hook basteln, falls es so ankommt.
https://docs.microsoft.com/en-us/win...sg/about-hooks


Es kann aber sein, dass diese Message hier nur an jene Fenster gesendet wird, welche sich vorher registriert haben.
https://docs.microsoft.com/en-us/win...enotificationa

Das Problem mit den an falscher Stelle behandelten/abgefangenen Messages, genauso wie für das übersehene SendMessage,
kann man sich da nun das WndProc seiner Form überschreiben oder die Message direkt anhängen,
Delphi-Quellcode:
procedure WndProc(var Message: TMessage); override;
bzw.
procedure WMDeviceChangeOderSo(var Message: TMessage); message WM_DEVICECHANGE; // hier geht statt TMessage auch ein passender Typ, siehe TWMSize in Forms.pas
oder man empfängt sowas in einem eigenen Thread mit einer unabhängigen "unsichtbaren" MessageOnly-Form (ähnlich der in Application).
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (10. Mär 2020 um 17:33 Uhr)
  Mit Zitat antworten Zitat
1967Schorsch

Registriert seit: 28. Feb 2020
Ort: Dinslaken
8 Beiträge
 
Delphi 6 Enterprise
 
#9

AW: COM Ports im System auslesen

  Alt 11. Mär 2020, 13:07
Hallo,
ich denke ich habe verstanden was du mir sagen willst.

Schade das es mit der Version (Delphi 6, ApplicationEvents Komponente) wohl nicht geht oder nicht so einfach ist.

Sich eine GetMessage-Hook basteln hört sich interessant an, nur wenn man (ich) nicht weis was man da tut, ist es schier unmöglich.
Schade und das nur um mitzubekommen ob der ausgewählte COM Anschluss/ USB Adapter abgesteckt wurde. Die Kommunikation über den Port erledigt ein anderes Programm was erst danach aufgerufen wird.

DANKE !!!
Georg
  Mit Zitat antworten Zitat
Antwort Antwort


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 09:51 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