AGB  ·  Datenschutz  ·  Impressum  







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

.exe zu .exe Kommunikation

Ein Thema von KodeZwerg · begonnen am 19. Apr 2018 · letzter Beitrag vom 16. Okt 2018
Antwort Antwort
Sailor

Registriert seit: 20. Jul 2008
Ort: Balaton
112 Beiträge
 
Delphi 2010 Professional
 
#1

AW: .exe zu .exe Kommunikation

  Alt 21. Apr 2018, 16:08
Warum benutzt Ihr nicht COM? Das ist doch genau dafür gedacht. Einen Server, einen oder mehrere Clients mit Eventsink für Kommunikation in beiden Richtungen: Delphi bietet alles an Komponenten, was man dazu braucht. Eine komfortable und sehr gut funktionierende Lösung.
  Mit Zitat antworten Zitat
günni0
(Gast)

n/a Beiträge
 
#2

AW: .exe zu .exe Kommunikation

  Alt 21. Apr 2018, 17:43
Und wenn Programm.exe schon offen ist, man nochmal Programm.exe startet und nur die Parameter von der zweiten an die erste Instanz geben will? Da finde ich COM,TCP und sowas etwas übertrieben.
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#3

AW: .exe zu .exe Kommunikation

  Alt 21. Apr 2018, 19:50
Ich (der TE) hatte dieses Problem, ich wollte das ein Hauptprogramm arbeitet und ein anderes Programm nur zuhört wie weit das Hauptprogramm mit Arbeit ist bzw an welcher Stelle es sich gerade befindet, ähnlich einem Debug nur viel simpler und keine Möglichkeit da einzugreifen, also kein "Chat-Programm" wo Nachricht hin und her geht sondern Einbahnstrasse.
Das Thema IPC war für mich bis dato neu sonst hätte ich garantiert weder einen Thread erstellt noch Thread-Titel so doof benannt, nun wurden mir diese und jene Varianten genannt also beschloss ich kurzerhand eine kleine Demo zu kreieren die einem alles was hier besprochen war enthält.
In der DP findet man massig Beispiele wenn man weiß wonach man suchen muss, ich wusste es vorher halt nicht.
Server-Seitig steht mein Konstrukt mit allen Features wie beim Bild weiter oben, Client-Seitig ist es (noch) komplizierter aber ich komme Stückchenweise voran.
Teilweise beissen sich die verschiedenen Typen wenn Sie gleichzeitig laufen (Client).
Bevor ich Schrottcode veröffentliche, Teste ich so gut ich kann alles was mir einfällt aus.
Client zeigt mehr Info's an als die eigentlich gesandten Daten, ich glaub ich mache es mir mit dem auch einfacher indem ich den die gleiche Auswahlbox verpasse anstelle permanent nach allen Varianten aktiv zu Suchen.
Spätestens in einer Woche sollte ich mit mir selbst Zufrieden sein so das ich Code freigebe.

edit
Client und Server kann man nur einmal starten, Reihenfolge ist egal.
Server sendet nur wenn Client zuhört.
Client gibt Zeit für Dauer an, deswegen Möglichkeit ein Bild zu senden/empfangen als example für Binär Daten.
Gruß vom KodeZwerg

Geändert von KodeZwerg (21. Apr 2018 um 19:57 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.283 Beiträge
 
Delphi 12 Athens
 
#4

AW: .exe zu .exe Kommunikation

  Alt 14. Sep 2018, 11:25
Ich greife diesen Thread mal auf, weil mein Anliegen thematisch hier sehr gut rein passt. Folgendes Problem bei mir:

1. Es soll zwei Programme geben. Eine Hostanwendung und eine oder mehrere Instanzen einer Client-Anwendung. Beide von mir geschrieben.

2. Die Hostanwendung ist ein Systemdienst, der unter dem SYSTEM-Konto läuft.

3. Die Hostanwendung startet die Client-Anwendung(en) selbst, Art und Weise wie diese Prozesse erzeugt werden, da bin ich flexibel.

4. Die Client-Anwendung beackert externe Programme, die wiederum NICHT von mir sind und hin und wieder mal zu Instabilität neigen. Raucht so ein Programm unerwartet ab, bleibt meine Client-Anwendung u.U. in einem undefinierten Zustand stehen. Deshalb sollen die Client-Anwendungen eine (konfigurierbare) Lifetime haben. Innerhalb derer müssen sie sich sauber beenden (wird in Datenbank geloggt). Tun sie das nicht, sollen sie zuerst vom Host per IPC eine Anweisung zum Shutdown bekommen (wird seitens Hostanwendung ebenfalls geloggt). Reagieren sie darauf auch nicht, z.B. per Antwort-Message und Shutdown, soll die Hostanwendung den hängenden Client-Prozess hart terminieren.

Soweit so einfach. Die Kommunikation zwischen meinen beiden Anwendungen ist eher trivial, eine einfache Event-Signalisierung, die keine komplexen Daten übermitteln muss. Schlimmstenfalls ein paar DWords.

Der Kniff an der Sache ist, dass die Client-Instanzen ggf. unter abweichenden Benutzerkonten gestartet werden müssen. Das hat mit den wiederum von den Client-Instanzen genutzten externen Programmen zu tun, die aus Sicherheitsgründen nicht im Systemkonto laufen. Darum scheidet wohl alles aus, das auf Window-Handles basiert. Welche Art IPC würdet ihr empfehlen für dieses Szenario?
Ich mache grundsätzlich keine Screenshots. Schießen auf Bildschirme gibt nämlich hässliche Pixelfehler und schadet der Gesundheit vom Kollegen gegenüber. I und E zu vertauschen hätte den selben negativen Effekt, würde aber eher dem Betriebsklima schaden
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.811 Beiträge
 
Delphi 12 Athens
 
#5

AW: .exe zu .exe Kommunikation

  Alt 14. Sep 2018, 12:29
TCP/IP über localhost sollte gehen, da die Ports systemweit einmalig sind.

Server Dienst hat einen fixen Port und Clients melden sich dort an und quatschen munter drauf los.

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

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

AW: .exe zu .exe Kommunikation

  Alt 14. Sep 2018, 12:39
Nja, am "Einfachten" und oft gemacht sind TCP/IP-Verbindungen. (dafür gibt es massenhaft ProcedureCall-Frameworks, wenn du nichts selberbauen willst)

Named-Pipes gingen auch, kommen vom Protokol auf das Gleiche.
Oder ohne Name, wenn du irgendwie anders die Handles übergibst.

Memory-Mapped-Files (MMF), aber für's "schicken" von Befehlen nicht so praktisch.
Also nur MMF ist schlecht, da man dann Pollen müsste, oder über andere Wege (Messages/Events/...) über neue Daten informiert.

WindowsMessages gingen, aber da gibt es leider nur die eine WM_COPYDATA, welche auch Texte/Daten übertragen kann (wobei man bei Texten das auch über WM_SETTEXT an ein/mehrere "EDITS" schicken könnte) und dann muß du alles da rein machen, wenn du verschiedene Messages schicken willst, z.B. über ein Byte/Flag am Anfang der Daten.
Und bei den Messages mußt du aufpassen, dass sich die Beiden diese Messages überhaupt schicken dürfen. (kennst z.B. von Anwendung an Admin-Anwendung, wo standardmäßig nicht alles erlaubt ist)
Alternativ zu WM_COPYDATA, die Daten in MMF, GlobalMemory oder Files und das Handle in LPARAM/WPARAM.
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (14. Sep 2018 um 12:44 Uhr)
  Mit Zitat antworten Zitat
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.739 Beiträge
 
Delphi 6 Enterprise
 
#7

AW: .exe zu .exe Kommunikation

  Alt 14. Sep 2018, 13:05
Mich würde auch mal interessieren, wie du Punkt 3 realisieren willst, wenn die unter einem anderen User laufen sollen. Wie macht man sowas?
Ralph
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.283 Beiträge
 
Delphi 12 Athens
 
#8

AW: .exe zu .exe Kommunikation

  Alt 14. Sep 2018, 13:11
Mich würde auch mal interessieren, wie du Punkt 3 realisieren willst, wenn die unter einem anderen User laufen sollen. Wie macht man sowas?
CreateProcessWithLogonW
Ich mache grundsätzlich keine Screenshots. Schießen auf Bildschirme gibt nämlich hässliche Pixelfehler und schadet der Gesundheit vom Kollegen gegenüber. I und E zu vertauschen hätte den selben negativen Effekt, würde aber eher dem Betriebsklima schaden
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.010 Beiträge
 
Delphi 2009 Professional
 
#9

AW: .exe zu .exe Kommunikation

  Alt 14. Sep 2018, 13:03
Hier ist ein Beispiel, in dem ein Indy TCP Server einem Client eine einfache Nachricht sendet. (Artikel Link)

Der Server-Code muss nur in der DoExecute-Methode angepasst werden und dort z.B. das nächste an den Client zu sendende Datenpaket erstellen. Da die Server-Klasse für jede Connection einen eigenen Thread verwendet, gilt der Code in der DoExecute Methode für die aktuelle Connection. DoExecute wird in einer Schleife ausgeführt bis die Verbindung getrennt wurde oder eine Exception auftritt.

Der Client-Code läuft in einem Thread um im Hintergrund auf neue Nachrichten des Servers zu warten. Der ReadLn Aufruf wartet, bis entweder eine Nachricht eintrifft, oder das Timeout erreicht ist, und wird dann wieder ausgeführt.

Delphi-Quellcode:
unit Unit1;
 
interface
 
uses
  IdCustomTCPServer, IdTCPClient, IdContext,
  SysUtils, Classes, Forms, StdCtrls, Controls;
 
type
  TMyPushClientThread = class(TThread)
  private
    TCPClient: TIdTCPClient;
    FLog: TStrings;
  public
    constructor Create(AHost: string; APort: Word; ALog: TStrings);
    destructor Destroy; override;
    procedure Execute; override;
  end;
 
  TMyPushServer = class (TIdCustomTCPServer)
  protected
    function DoExecute(AContext: TIdContext): Boolean; override;
  end;
 
  TServerPushExampleForm = class(TForm)
    MemoLog: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    ExampleClient: TMyPushClientThread;
    ExampleServer: TMyPushServer;
  end;
 
var
  ServerPushExampleForm: TServerPushExampleForm;
 
implementation
 
uses
  IdGlobal;
 
{$R *.dfm}
 
procedure TServerPushExampleForm.FormCreate(Sender: TObject);
begin
  ExampleServer := TMyPushServer.Create;
  ExampleServer.DefaultPort := 8088;
  ExampleServer.Active := True;
 
  ExampleClient := TMyPushClientThread.Create('localhost', 8088, MemoLog.Lines);
end;
 
procedure TServerPushExampleForm.FormDestroy(Sender: TObject);
begin
  ExampleServer.Free;
  ExampleClient.Terminate;
  ExampleClient.WaitFor;
  ExampleClient.Free;
end;
 
{ TMyPushServer }
 
function TMyPushServer.DoExecute(AContext: TIdContext): Boolean;
begin
  Result := inherited;
 
  // simulate hard work
  Sleep(Random(3000));
 
  AContext.Connection.IOHandler.WriteLn(
    'Completed at ' + TimeToStr(Now), IndyTextEncoding_UTF8);
end;
 
{ TMyPushClientThread }
 
constructor TMyPushClientThread.Create(AHost: string; APort: Word; ALog: TStrings);
begin
  inherited Create(False);
 
  FLog := ALog;
 
  TCPClient := TIdTCPClient.Create;
  TCPClient.Host := AHost;
  TCPClient.Port := APort;
  TCPClient.ReadTimeout := 500;
end;
 
destructor TMyPushClientThread.Destroy;
begin
  TCPClient.Free;
  inherited;
end;
 
procedure TMyPushClientThread.Execute;
var
  S: string;
begin
  TCPClient.Connect;
 
  while not Terminated do
  begin
    S := TCPClient.IOHandler.ReadLn(IndyTextEncoding_UTF8);
 
    if not TCPClient.IOHandler.ReadLnTimedout then
    begin
      TThread.Queue(nil,
        procedure
        begin
          FLog.Append(S);
        end);
    end;
 
  end;
 
  TCPClient.Disconnect;
end;
 
end.
Michael Justin
  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 06: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