![]() |
Kommunikation zwischen zwei Delphiprogrammen
Liebe Freunde,
heute bitte ich Euch um allgemeine Hinweise, Tips und Ratschläge um folgende, für mich ganz neue, Aufgabenstellung zu lösen. Ich möchte ein Delphiprogramm (mit Delphi Professional 10.4.2) schreiben, dass eine GUI hat, aber dennoch etwas für mich erledigt, wenn ich es unter W8.1 verkleinere, es also in der Taskleiste landet. Ein zweites Programm soll einige Parameter an das Erste schicken können. Dort wird etwas berechnet und dann das Ergebniss an das zweite Programm zurückgeschickt. (compute server?) Mit welchen Standartkomponenten kann ich das erreichen? Wenn es irgendwie ginge, würde ich gerne Mechanismen des Betriebssystems umgehen und die Programme sozusagen direkt miteinander kommunizieren lassen. An folgende Lösungen habe ich schon gedacht. A) Das zweite Programm ruft das Erste direkt auf (startet es) und übergibt dabei die Parameter. Dann wird das Ergebniss über die Zwischenablage zurückgegeben. Das ist leider langsam und braucht die Zwischenablage. B) Ich lasse ein drittes Programm mit einer Datenbank laufen, auf das die ersten beiden Programme auch Zugriff haben. Wenn ich die Datenbank im RAM laufen lasse ist das sogar recht schnell aber es ist mit mehr Aufwand verbunden. Welche elegantere Lösungen gibt es? Herzlichen Dank im voraus. RWB |
AW: Kommunikation zwischen zwei Delphiprogrammen
Im allgemeinen verwendet man IPC (Inter Process Communication) dafür.
Da Du schreibst "ohne Mechanismen des Betriebssystems" auskommen zu wollen wird dir wohl nichts was IPC betrifft zusagen. |
AW: Kommunikation zwischen zwei Delphiprogrammen
Hallo KodeZwerg,
ersteinmal danke für die Antwort. Auch wenn ich Vorlieben habe, hier also das Betriebssystem zu umgehen, kann es ja sein, dass das der einzige Weg ist. Ich bin daher offen für alle Vorschläge. Gibt es Komponenten für IPC? Wie geht man das praktisch an? |
AW: Kommunikation zwischen zwei Delphiprogrammen
Dazu kurz zwei Stichworte:
Named Pipe Sockets, entweder TCP oder UDP Für letzteres entweder Indy nehmen, ist aber synchron oder ICS (siehe Tools/GetIt), das wäre nicht blockierend asynchron. Grüße TurboMagic |
AW: Kommunikation zwischen zwei Delphiprogrammen
Zitat:
Du kannst hier nur versuchen einen Weg zu finden, welcher z.B. nicht nur unter Windows verfügbar ist, sondern auch auf Linux gehen würde. |
AW: Kommunikation zwischen zwei Delphiprogrammen
Die einfachste und in der Regel idiotensichere Möglichkeit, Daten von einem Programm an ein anderes zu übergeben, ist via Dateien.
Beispiel: Es gibt ein Verzeichnis A mit Eingabedateien und Verzeichnis B mit Ausgabedateien. Programm 1 schreibt seine Daten, die berechnet werden sollen, in Verzeichnis A, Programm 2 wartet darauf, dass in Verzeichnis A Dateien angelegt werden, liest sie, verarbeitet sie und schreibt das Ergebnis in Verzeichnis B. Programm 1 wartet darauf, dass seine Ergebnisse in Verzeichnis B erscheinen und liest sie dann aus. Das ist sicherlich nicht die schnellste, eleganteste und sicherste Lösung, aber es lässt sich wunderbar debuggen und testen. Ach ja, und es funktioniert auch auf einem Share im Netzwerk. Man darf sich nur nicht von irgendwem erwischen lassen, dass man so eine simple Lösung verwendet statt irgendeines "Frameworks" oder einer Datenbank (wobei die schon Old School sind) oder eines "Microservices". |
AW: Kommunikation zwischen zwei Delphiprogrammen
Die einfachste Lösung wäre doch per http...
Die eine App mach einen http oder REST Server auf... Die andere kann dann einfach per JSON die Anfrage senden und so auch die Antwort erhalten. Mavarik PS.: Also im Prinzip das, was TurboMagic schon geschrieben hat, nur einen Layer mehr. |
AW: Kommunikation zwischen zwei Delphiprogrammen
Auch das sollte mit ICS gehen oder vermutlich auch mit Indy, wenn es blockieren darf.
|
AW: Kommunikation zwischen zwei Delphiprogrammen
Liste der Anhänge anzeigen (Anzahl: 2)
Ich nutze hierfür Namend Pipes. Dafür gibt es eine Freeware Komponente, die das Ganze sehr einfach machen. Diese Freeware Komponente habe ich dir mal angehängt. Ich nutze dies schon sehr lange zum Steuern eines Windwosdienstes über ein Trayicon Programm.
|
AW: Kommunikation zwischen zwei Delphiprogrammen
Ich bin begeistert, herzlichen Dank an alle.
Jetzt werde ich ersteinmal alle Vorschläge überdenken und habe dann bestimmt weitere Fragen. Ich wünsche allen ein tolles bzw besinnliches Wochenende. RWB |
AW: Kommunikation zwischen zwei Delphiprogrammen
Hallo,
Ihre Lösung gefällt mir, ich könnte eine Textdate mit den Daten auf jeweils einer Zeile anlegen. Die Datei hätte mehrere Zeilen. Damit wäre auch eine Batchverarbeitung möglich. Dabei geht es mir dann auch nicht um Schnelligkeit. Aber hier liegt der Haken: >Programm 1 schreibt seine Daten, die berechnet werden sollen, in Verzeichnis A, Programm 2 wartet darauf, dass in Verzeichnis A Dateien angelegt werden, Es ist das warten von Programm 2, also die Überwachung eines Verzeichnisses. Ich habe einen ziemlichen Teil des Sonntags damit verbracht dafür eine praktikable Lösung zu suchen. Hier in der Delphi-Praxis gibt es eine ganze Reihe von Beiträgen zu diesem Thema. Aber sie sind ziemlich alt mit Verweisen auf Webseiten die nicht mehr existieren mit anderen gebrochenen Links und Beiträgen die Probleme aufzeigen aber keine Lösung. In der JCVL gibt es die Komponenten JvChangeNotify und TJvFolderMonitor. Leider brach die Installation der JXVL mit einem Fehler ab. Hiermit komme ich also zur Zeit auch nicht weiter. Es gibt eine Watch_it.exe die Verzeichnisse überwacht und Aktionen auslöst. Ich brauch aber eine Unit oder Komponente die ich einbinden kann. Wie haben Sie das gelöst? >Man darf sich nur nicht von irgendwem erwischen lassen, dass man so eine simple Lösung verwendet statt irgendeines "Frameworks" oder einer Datenbank (wobei die >schon Old School sind) oder eines "Microservices". Da habe ich keine Angst :-D Mit besten Grüßen RWB |
AW: Kommunikation zwischen zwei Delphiprogrammen
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
WM_COPYDATA wird benutzt um was von Programm A zu Programm B zu senden. Funktioniert bei mir immer tadellos, habe eine kleine Demo dazu angehangen. Viel spaß beim testen. |
AW: Kommunikation zwischen zwei Delphiprogrammen
Zitat:
Aber: bei einer fehlgeschlagenen JVCL Installation werden wir dir da nur weiterhelfen können, wenn du uns die Fehlermeldung nennst. Wir haben leider keine Glaskugeln... Hast du zuerst die JCL installiert? Wie bist du zur Installation vorgegangen? Via Tools/GetIt Packagemnager? |
AW: Kommunikation zwischen zwei Delphiprogrammen
Zitat:
Bis bald... Thomas |
AW: Kommunikation zwischen zwei Delphiprogrammen
Liste der Anhänge anzeigen (Anzahl: 1)
Moin
>Hast du zuerst die JCL installiert? >Wie bist du zur Installation vorgegangen? Via Tools/GetIt Packagemnager? Ja, genau Tools/GetIt Packagemaneger, glücklicherweise hatte ich direct einen Screenshot gemacht. Ist angehängt. Danach habe ich mir heruntergeladen: JVCL349CompleteJCL27-Build5676.zip ![]() ![]() aber damit komme ich nicht klar. |
AW: Kommunikation zwischen zwei Delphiprogrammen
Korrektur,
inzwischen konnte ich die jvcl von der jvcl-master.zip installieren. |
AW: Kommunikation zwischen zwei Delphiprogrammen
>Viel spaß beim testen.
Danke KodeZwerg, den Spaß hatte ich. Hat auf Anhieb funktioniert. Den Code sehe ich mir morgen an. |
AW: Kommunikation zwischen zwei Delphiprogrammen
Zitat:
|
AW: Kommunikation zwischen zwei Delphiprogrammen
Zitat:
Es gibt dafür aber die WinAPI Funktionen FindFirstChangeNotification / FindNextChangeNotification, die ich z.B. in ![]() Der Code läuft in einem Hintergrundthread und sieht so aus:
Delphi-Quellcode:
Im Prinzip könntest Du diesen Code nutzen, müsstest nur in CheckForFile die Verarbeitung vornehmen. Und natürlich in FindFirstNotification statt TFileSystem.GetTempPath das korrekte Verzeichnis übergeben.
procedure Tf_EditorLineEndsFix.ExecuteInThread(_Sender: TObject);
var Err: DWORD; NotifyHandle: THandle; Res: DWORD; begin try CheckForFile; NotifyHandle := FindFirstChangeNotification(PChar(TFileSystem.GetTempPath), false, FILE_NOTIFY_CHANGE_FILE_NAME); if NotifyHandle = INVALID_HANDLE_VALUE then begin Err := GetLastError; RaiseLastOsErrorEx(Err, _('Error %1:s (%0:d)')); end; try while not TThread.CheckTerminated do begin Res := WaitForSingleObject(NotifyHandle, 100); if res = WAIT_OBJECT_0 then begin CheckForFile; if not FindNextChangeNotification(NotifyHandle) then begin Err := GetLastError; RaiseLastOsErrorEx(Err, _('Error %1:s (%0:d)')); end; end else if res = WAIT_TIMEOUT then begin // stay in the loop end else raise Exception.CreateFmt(_('WaitForSingleObject failed with error code %d.'), [res]); end; finally FindCloseChangeNotification(NotifyHandle); end; except on e: Exception do begin doWriteToLog(e.Message); end; end; end; Und nicht vergessen: Der Code sollte in einem Hintergrund-Thread laufen, sonst blockiert er das UI. |
AW: Kommunikation zwischen zwei Delphiprogrammen
Ein kleiner Hinweis noch zum Mechanismus mit den Dateien, denn damit hatte ich vor längerem zu tun.
Ich habe (kleine) Auftrags-Dateien erzeugt, der Server hat die gelesen, diese Dateien gelöscht und Antwort-Dateien erzeugt, die dann wiederun der Client gelesen und gelöscht hat. Im lokalen Dateisystem funktioniert so etwas sehr gut und auch stabil. Auf Netzlaufwerken sollte man allerdings vorsichtig sein. Seit der Einführung des SMB2-Protokoll gab es massive Probleme (das Zurückschalten auf SMB1 ist aus Sicherheitsgründen nicht zu empfehlen). Bei sehr vielen Dateioperationen auf den Windows-Freigaben kann es sehr lange dauern, bis die Änderungen für den Client sichtbar sind, egal ob im Windows-Explorer oder den FindChangeNotifications, teilweise waren das 10 Sekunden! Im Endeffekt haben wir den Dateimechanismus durch http ersetzt und seit dem keine Probleme. |
AW: Kommunikation zwischen zwei Delphiprogrammen
Danke, ich bastele jetzt mit den verschiedenen Ansätzen rum, und wenn was dabei rauskommt melde ich mich.
Danke noch mal an Alle für Ihre Beiträge. RWB |
AW: Kommunikation zwischen zwei Delphiprogrammen
Zitat:
Solange die Anwendung kontinuierlich läuft, und das Netzwerkverzeichnis erreichbar ist, funktioniert es auch prima. Doch nach einer Netzwerkstörung, wegen der das Programm den Incoming-Ordner vorübergehend nicht sieht, oder einem Neustart des Programms, liegen eventuell Dateien im Incoming-Ordner, die zwischenzeitlich eingetroffen sind. Daher muss man beim Start des Programms dann zusätzlich noch einmal einen normalen Directory-Scan durchführen. So gesehen hat man dann zwei Schleifen für ein und dieselbe Aufgabe. Zur Kommunikation zwischen zwei Prozessen würde ich entweder das klassische Suchen im Dateisystem (Findxxx) verwenden, oder eine andere Methode für IPC. Client-Server basierte Lösungen jedoch nur mit einem zentralen Server. Nicht auf jedem Rechner im lokalen Netz möchte die IT "wilde" HTTP- oder sonstige offene Server-Ports sehen :) |
AW: Kommunikation zwischen zwei Delphiprogrammen
Zitat:
Problem: Es kann bei TPipeServer beim Beenden der Verbindung (Active := false) ein Speicherleck entstehen: Soweit ich sehe passiert es, wenn ein TPipeClient Disconnect aufruft und TPipeServer "gleichzeitig" mittels Write diesem Client Daten D übermittelt und dann Active := false setzt. In der Methode TPipeServer.Write wird via AllocPipeWrite für D Speicher reserviert. DisposePipeWrite wird aber für diesen Speicher dann nicht aufgerufen => Leck. (EurekaLog 7.11.0.1) Lösung: Code der Komponente anpassen. Workaround (Lösung wäre schöner ;-)): Bei 1-1 Verbindung: TPipeServer schliesst die Verbindung. Bei 1-n Verbindungen: Flusskontrolle einbauen. |
AW: Kommunikation zwischen zwei Delphiprogrammen
Moin Michael II,
wie benutze ich denn jetzt das Ganze? Mein Programm(e) ist in der IDE, ich lade die beiden Dateien, nehme sie in die USES auf und dann? Ratlos, RWB |
AW: Kommunikation zwischen zwei Delphiprogrammen
Hoi rwb,
falls du noch nie eine eigene ![]() Zur Pipe: Wähle in deinem Delphi das Menu Komponente > ![]() In RFNamedPipes.pas gibt's eine Procedure Register RegisterComponents('Win32', [TPipeServer, TPipeClient]); Nach der Installation der Komponente findest du deshalb in der IDE in der Palette unter Win32 neu TPipeServer und TPipeClient. Du hast zwei Apps 1 und 2, welche via Pipe kommunizieren sollen? Knall auf 1 TPipeServer und auf 2 TPipeClient. Setze die Eigenschaft PipeName in 1 und 2 auf den gleichen Wert. Setze die Eigenschaft Active von TPipeServer auf true. TPipeServer wartet nun auf Verbindungsanfragen. TPipeClient kann mittels Connect verbinden. Mit Write übermittelst du Daten. Auf der Gegenseite greifst du die empfangenen Daten im OnMessage ab. Verbindung abbrechen: Client seitig: Disconnet. Server seitig: Active := false setzen (es gibt auch eine protected Methode, welche dich vielleicht interessiert, wenn du mehrere Clients hast und zu einem bestimmten Client die Verbindung kappen willst - schau in den Code) Ich hoffe das hilft. |
AW: Kommunikation zwischen zwei Delphiprogrammen
Hervorragend Danke
|
AW: Kommunikation zwischen zwei Delphiprogrammen
Was ist mit dem App-Tethering? Das sollte doch auch funktionieren. Habe bisher wenig Erfahrung damit, nur mal ein Übungsbeispiel (Bild mit Handy fotografieren und dann zum Desktop schicken) das geht einwandfrei.
Oder gibt es damit Probleme die ich nicht kenne? |
AW: Kommunikation zwischen zwei Delphiprogrammen
Zitat:
|
AW: Kommunikation zwischen zwei Delphiprogrammen
Zitat:
Und ich würde wie TM (#4) tcp und dazu ICS Overbyte nutzen. Wenn ich die ![]() Ich habe hier nur reingeschrieben wegen dem Leck in #9. Ich nutze die Pipe (#9) als Alternative zur einer tcp Verbindung. Da es NutzerInnen meiner App immer wieder gelingt mittels Firewall die Verbindung zu kappen ist ein zweiter Weg ganz gut. |
AW: Kommunikation zwischen zwei Delphiprogrammen
Die Wahl einer Lösung hängt natürlich auch immer vom persönlichen Geschmack ab. Das macht eine Lösung aber nicht zwingend zu einer besseren oder schlechteren.
|
AW: Kommunikation zwischen zwei Delphiprogrammen
Zitat:
(Ich nutze diese Komponenten für die Kommunikation zwischen zwei Apps auf dem gleichen Gerät. Früher habe ich tcp via ICS verwendet; da gab's halt immer wieder Menschen, welche ihre Firewall o.ä. nicht bedienen konnten und sich aussperrten. => Der Support ist in diesem Bereich von mehreren Stunden pro Jahr auf 0 gefallen.) |
AW: Kommunikation zwischen zwei Delphiprogrammen
Hi,
hier ist meine aktuelle 32+64-Bit-Version mit noch weiteren Verbesserungen und einem Beispiel-Programm. Man kann das Programm mehrmals starten, um zu sehen, dass sich mehrere Clients mit demselben Server verbinden können. ![]() Ich habe eine ähnliche Unit auch für macOS/Linux, die mit Sockets arbeitet. Bei Interesse bitte nachfragen. |
AW: Kommunikation zwischen zwei Delphiprogrammen
Herzlichen Dank für die rasche Hilfe an diesem "Sturm und Schneeregen Sonntag".
Eingebaut - Funktioniert 1A :-D |
AW: Kommunikation zwischen zwei Delphiprogrammen
Ich mache das seit Jahren mit allen möglichen Delphi Versionen mit Cromis IPC.
|
AW: Kommunikation zwischen zwei Delphiprogrammen
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:09 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