Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Externen Prozess starten und beenden (https://www.delphipraxis.net/209862-externen-prozess-starten-und-beenden.html)

Rainer Wolff 2. Feb 2022 08:20

Delphi-Version: 10.4 Sydney

Externen Prozess starten und beenden
 
Hallo,

ich weiss, es gibt schon einige Threads über dieses Thema, aber ich habe noch nichts gefunden, was funktioniert.

Ich starte einen externen Prozess (eine dotnet Rest-API) über ShellExecute direkt im Projektfile, bevor die ersten Forms oder Datenmodule erstellt werden.
Das funktioniert auch.

Diesen Prozess will ich stoppen, wenn das Delphi-Programm beendet wird. Nun habe ich zwei Probleme:

1. Wo kann ich den Aufruf zum Prozessende unterbringen? Ich will den Prozess erst stoppen, wenn alle Delphi-Komponenten beendet worden sind. Ich hatte den Aufruf hinter das Application.Run gehängt, aber da werden die nachfolgenden Befehle ausgeführt, bevor alle Komponenten freigegeben werden. Gibt es etwas Application.OnTerminate oder ähnliches, um bei Programmende noch Code auszuführen
2. Das Killen meines Prozesses funktioniert nicht, weder mit TerminateProzess, noch mit einer anderen Methode, die ich gefunden habe. Hängt das eventuell damit zusammen, daß es sich um einen Dotnet-Prozess handelt?

Andreas13 2. Feb 2022 08:28

AW: Externen Prozess starten und beenden
 
Schau doch mal hier rein: https://www.delphi-treff.de/tipps-tr...ndung-beenden/, vielleicht hilft es Dir weiter.
Gruß, Andreas

shebang 2. Feb 2022 08:48

AW: Externen Prozess starten und beenden
 
Zitat:

Zitat von Rainer Wolff (Beitrag 1501545)
Ich starte einen externen Prozess über ShellExecute

Wenn du ihn mit CreateProcess startest, kannst du dir das Handle merken, welches du für TerminateProcess brauchst.

Der schöne Günther 2. Feb 2022 10:23

AW: Externen Prozess starten und beenden
 
CreateProces(..) oder ShellExecuteEx(..)

In jedem Fall ist etwas wie TerminateProcess(..) aber fast gleichzusetzen, als würde man sich von hinten an jemand heranschleichen und ihn erdolchen. Man gibt dem Prozess keine Möglichkeit sich selbst kontrolliert zu beenden.

Wenn es eine Hintergrund-Anwendung ist die gar nicht für den Benutzer sichtbar sein soll dann lassen die sich oft über einen Konsolenbefehl ("quit") oder die Tastenkombo [strg]+[c] kontrolliert beenden.

Aber vielleicht ist es ja auch gar schlimm das Programm mit Gewalt abzumurksen, das weiß nur der Entwickler selbst 😉

Rainer Wolff 2. Feb 2022 11:20

AW: Externen Prozess starten und beenden
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1501553)
CreateProces(..) oder ShellExecuteEx(..)

In jedem Fall ist etwas wie TerminateProcess(..) aber fast gleichzusetzen, als würde man sich von hinten an jemand heranschleichen und ihn erdolchen. Man gibt dem Prozess keine Möglichkeit sich selbst kontrolliert zu beenden.

Wenn es eine Hintergrund-Anwendung ist die gar nicht für den Benutzer sichtbar sein soll dann lassen die sich oft über einen Konsolenbefehl ("quit") oder die Tastenkombo [strg]+[c] kontrolliert beenden.

Aber vielleicht ist es ja auch gar schlimm das Programm mit Gewalt abzumurksen, das weiß nur der Entwickler selbst 😉

Das abmurksen an sich wäre nicht das Problem, aber der Prozess gehorcht nicht. Ich habe jetzt auch die beiden o.a. Lösungen getestet, starte den Prozess mit CreateProcess und erhalte ein hProcess zurück.
Aber Terminate will nicht.

Ein Control-C würde wohl auch funktionieren, muss ich mal googeln, wie ich das zum Prozess schicken kann.

Das zweite Problem ist aber auch noch ungelöst: Der Prozess soll erst beendet werden, wenn sich die Delphi-Komponenten verabschiedet haben.

P.S.: Günther: es handelt sich bei dem Prozess um meinen neuen OPC-UA-Wrapper, den ich nicht in C++ mit open62541, sondern in DotNet mit der dortigen UA-Bibliothek zusammengewurstelt habe.

Uwe Raabe 2. Feb 2022 11:37

AW: Externen Prozess starten und beenden
 
Zitat:

Zitat von Rainer Wolff (Beitrag 1501560)
Das zweite Problem ist aber auch noch ungelöst: Der Prozess soll erst beendet werden, wenn sich die Delphi-Komponenten verabschiedet haben.

Das ist in der Tat schwierig, da die erzeugten Forms und DataModules in der Regel erst im DoneApplication freigegeben werden. Das ist private und wird normalerweise im Zuge der ExitProcs aufgerufen, zu denen auch die Finalization-Bereiche der Units gehören.

Wenn du also unbedingt etwas ausführen musst, dann pack das in das finalization einer neuen Unit und setze die in der DPR an die erste Stelle der uses-Anweisung. In der Unit darf dann natürlich nicht sowas wie Vcl.Forms stehen oder so. Was auch immer du da machst muss mit möglichst wenig externen Referenzen auskommen.

Eventuell reicht es aber auch, sich in das OnDestroy des als erstes erzeugten Forms/DataModules einzuhängen.

KodeZwerg 2. Feb 2022 11:56

AW: Externen Prozess starten und beenden
 
oder ohne viel aufwand über eine batch starten, als exitcode das handle geben so das es außerhalb deiner app.exe instanz verwendet werden kann um den besagten prozess zu terminieren.
unschön aber effektiv.

//edit
aufbauend auf diesen gedanken kann man ja auch der externen app beibringen auf parameter zu gehorchen falls das technisch bei dir überhaupt möglich ist/sinn macht
so in etwa
Delphi-Quellcode:
@echo off
service.exe /start
application.exe
service.exe /stop

shebang 2. Feb 2022 12:51

AW: Externen Prozess starten und beenden
 
Zitat:

Zitat von Rainer Wolff (Beitrag 1501560)
Aber Terminate will nicht.

Wie ist denn der Rückgabewert von TerminateProcess und der evtl. zugehörige Fehlercode?


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:26 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