Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Anderes Programm beenden (https://www.delphipraxis.net/204348-anderes-programm-beenden.html)

zeras 21. Mai 2020 11:29


Anderes Programm beenden
 
Hallo,

für Testzwecke möchte ich ein externes Programm starten und nach einiger Zeit wieder beenden.
Im Forum habe ich verschiedene Ansätze gefunden. Die einen machen das mit
Delphi-Quellcode:
TerminateProcess
, die anderen mit
Delphi-Quellcode:
SendMessage(GetWindowFromID(GetProcessID(programm)), WM_CLOSE, 0, 0); //Programm beenden senden
Was ist der Unterschied zwischen den Funktionen? Was sollte man am besten nehmen? Oder gibt es noch weitere Funktionen, die man nehmen kann?

Bernhard Geyer 21. Mai 2020 11:39

AW: Anderes Programm beenden
 
TerminateProcess ist ein hartes beenden des anderen Programmes ohne ihm die Möglichkeit zu geben Daten zu sichern.
Ein WM_CLOSE ist der normale Weg (wie auch beim Klick auf das x rechts oben am Fenster der Anwendung.

zeras 21. Mai 2020 11:43

AW: Anderes Programm beenden
 
Zitat:

Zitat von Bernhard Geyer (Beitrag 1464992)
Ein WM_CLOSE ist der normale Weg (wie auch beim Klick auf das x rechts oben am Fenster der Anwendung.

Dann werde ich das nehmen. Das scheint mir besser für meinen Test.

Danke.

Andreas13 21. Mai 2020 13:09

AW: Anderes Programm beenden
 
Hallo Zeras,
vielleicht hilft Dir dieser Link weiter: https://www.delphi-treff.de/tipps-tr...ndung-beenden/. Die dort beschriebene Methode benutze ich seit vielen Jahren mit gutem Erfolg.
Gruß, Andreas

zeras 21. Mai 2020 13:39

AW: Anderes Programm beenden
 
Danke auch für die weiteren Infos.
So wie es scheint, kann ich das Programm beenden.
Mein nächstes Problem ist nun aber, dass das Programm mehrmals gestartet wird und ich die Programme wieder in einer vorgegebenen Reihenfolge beenden muss.
Starten tue ich das so
Delphi-Quellcode:
  ShExecInfoW.Wnd := GetForegroundWindow;
  ShExecInfoW.cbSize := SizeOf(SHELLEXECUTEINFOW);
  ShExecInfoW.fMask := SEE_MASK_NOCLOSEPROCESS;
  ShExecInfoW.lpVerb := 'open';
  ShExecInfoW.lpFile := PWideChar(WideString(Filename));
  ShExecInfoW.lpParameters := PWideChar(WideString(Para));
  ShExecInfoW.lpDirectory := PWideChar(WideString(ExtractFileDir(Filename)));
  ShExecInfoW.nShow := WindowState;
  Result := ShellExecuteExW(@ShExecInfoW);
ShExecInfoW habe ich mir dann gemerkt, weiß aber nicht, wie ich das zum Beenden nutze.
Mit Fenster Handles, Process Handles usw. habe ich bisher noch nichts zu tun gehabt.

himitsu 21. Mai 2020 14:07

AW: Anderes Programm beenden
 
Du kannst es mit deinem eigenen Programm gern ausprobieren.

Denn es ist auch im Taskmanager der Unterschiet zwischen den Tabs "Prozesse" und "Details".
In Prozesse wird ein WM_CLOSE ans Hauptfenster WM_QUIT an den Prozess (Hauptthread) gesendet,
während in Details ein TerminateProcess ausgeführt wird.

Und ein Klick auf's [X], bzw. das Schließen im Taskleisten-Button sendet das WM_CLOSE ans dortige Fenster. (in uralten Delphis, bzw. bei Application.MainFormOnTaskbar=False, landet das von der Taskleiste nicht im MainForm.Handle, sondern geht an Application.Handle)



Entweder du merkst dir vom MSDN-Library durchsuchenCreateProcess das ProzessHandle oder die ProzessID
oder via MSDN-Library durchsuchenGetProcessTimes bekommst du die Startzeit.


Wenn deine Variablen compilerabhängige "Strings" sind, warum machst du es dir nicht einfach und nimmst dafür auch die compilerabhängigen Typen und Funktionen?
Delphi-Quellcode:
  // nicht die W/Wide oder A/Ansi, sondern die OHNE
  ...
  ShExecInfo.lpFile := PChar(Filename);
  ShExecInfo.lpParameters := PChar(Para);
  ShExecInfo.lpDirectory := PChar(ExtractFileDir(Filename));
  ...
  Result := ShellExecuteEx(@ShExecInfo);

zeras 21. Mai 2020 18:19

AW: Anderes Programm beenden
 
Danke himitsu,

ich habe nun statt
Delphi-Quellcode:
ShellExecuteEx
Delphi-Quellcode:
CreateProcess
genutzt und dann die ProzessID gemerkt. Dann kann ich bei Beenden
Delphi-Quellcode:
SendMessage(GetWindowFromID(dwProcessId), WM_CLOSE, 0, 0);
nutzen und alles ist OK.
Auch deine Hinweise wegen Ansi und Wide habe ich umgesetzt. Ich hatte ein altes Beispiel genutzt und dort war es noch so beschrieben.

Jetzt muss ich nur noch versuchen, die Fensterpositionen zu merken, damit die beim nächsten Start der Programme wieder an derselben Stelle angezeigt werden.
Aber da werde ich bestimmt hier im Forum noch fündig

Danke nochmals.


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