AGB  ·  Datenschutz  ·  Impressum  







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

ShellExecuteEx + TerminateProcess

Ein Thema von shebang · begonnen am 22. Apr 2021 · letzter Beitrag vom 27. Apr 2021
Antwort Antwort
Seite 1 von 3  1 23      
shebang
Online

Registriert seit: 7. Feb 2020
97 Beiträge
 
Delphi 11 Alexandria
 
#1

ShellExecuteEx + TerminateProcess

  Alt 22. Apr 2021, 11:32
Hallo,

ich verwende ShellExecuteEx um eine Konsole zu starten, die einen Befehl ausführt und die Ausgabe in eine Textdatei umleitet soll. Da der Befehl kontinuierlich Daten erzeugt, möchte ich ihn irgendwann abbrechen. Dafür sollte doch TerminateProcess geeignet sein. Das Problem ist, das Beenden funktioniert nicht. Für das Bespiel hier habe ich einfach ping verwendet und die Umleitung weggelassen, da sie für das eigentliche Problem nicht wichtig ist. Ich habe also eine Form mit zwei Buttons und den folgenden Funktionen erstellt:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  ShExecInfo.cbSize := SizeOf(ShellExecuteInfo);
  ShExecInfo.fMask := SEE_MASK_NOCLOSEPROCESS;
  ShExecInfo.lpVerb := 'open';
  ShExecInfo.lpFile := 'cmd.exe';
  ShExecInfo.lpParameters := '/c ping -t delphipraxis.net';
  ShExecInfo.nShow := SW_SHOW;

  if not ShellExecuteEx(@ShExecInfo) then raise Exception.Create('ShellExecuteEx error = ' + IntToStr(GetLastError));
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  if not TerminateProcess(ShExecInfo.hProcess, 0) then raise Exception.Create('TerminateProcess error = ' + IntToStr(GetLastError));
end;
Das Flag SEE_MASK_NOCLOSEPROCESS führt dazu, dass das Process handle in der Variablen ShExecInfo.hProcess gespeichert wird. Es gibt keinerlei Fehlermeldung, aber der Prozess wird nicht beendet. Was mache ich falsch? Gibt es eine andere Möglichkeit die Konsole zu schließen?

PS: CreateProcess verwende ich nicht, da dort die Umleiten der Ausgabe in eine Datei nicht funktioniert.
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.110 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: ShellExecuteEx + TerminateProcess

  Alt 22. Apr 2021, 12:43
Der Doku "How Processes are Terminated" nach:
Zitat:
(...)
For console processes, the default console control handler calls ExitProcess when the console receives a CTRL+C or CTRL+BREAK signal.
(...)
Da du den Prozess ja über seine eigene, neue Konsole laufen lässt ist wahrscheinlich der einfachste Weg, die Anwendung in einem Job laufen zu lassen und diesen dann notfalls zu beenden.


Wenn ich das allerdings anmerken darf, das ganze erscheint trotzdem etwas Quick & Dirty. Bist du sicher, dass beispielsweise der Umweg über Dateien auf der Festplatte notwendig ist? Das tolle an Konsolenanwendungen ist eigentlich dass du die direkt aus deiner Delphi-Anwendung über Pipes (StdIn, StdOut, StdErr) auslesen und füttern kannst wie der Mensch der das schwarze Konsolenfenster mit der Tastatur bedient.

PS: Ja, dass es mit Jobs zu funktioniert bestätigt hier jemand. Trotzdem hätte ich gesagt dass der jetzige Ansatz wirklich nicht optimal ist.
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.680 Beiträge
 
Delphi 5 Professional
 
#3

AW: ShellExecuteEx + TerminateProcess

  Alt 22. Apr 2021, 13:28
Bist du sicher, dass der Prozess nicht beendet wird? Du killst cmd.exe, aber die Ausgabe kommt von ping.exe. Führt man eine CMD von Hand aus (mit ping auf irgendeinen Host) und killt per Task-Manager die cmd.exe, bleibt das Konsolenfenster dennoch offen und wird erst bei Abbruch der ping.exe (z.B. per Strg+C) geschlossen.

Grüße
Dalai
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.685 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: ShellExecuteEx + TerminateProcess

  Alt 22. Apr 2021, 13:31
Delphi-Referenz durchsuchenAttachConsole bzw Delphi-Referenz durchsuchenAllocConsole sollte doch funktioniert und im Cancel-Event dann Delphi-Referenz durchsuchenFreeConsole oder?

Aber ja, wenn es ein anderes Programm ausführt bringt das nicht viel....
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
shebang
Online

Registriert seit: 7. Feb 2020
97 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: ShellExecuteEx + TerminateProcess

  Alt 22. Apr 2021, 14:31
Bist du sicher, dass beispielsweise der Umweg über Dateien auf der Festplatte notwendig ist? Das tolle an Konsolenanwendungen ist eigentlich dass du die direkt aus deiner Delphi-Anwendung über Pipes (StdIn, StdOut, StdErr) auslesen und füttern kannst wie der Mensch der das schwarze Konsolenfenster mit der Tastatur bedient.
Die Daten, die in die Datei geschrieben werden sollen, benötige ich innerhalb meiner Delphi-Anwendung gar nicht. Die sind für eine spätere externe Auswertung vorgesehen. Ich möchte im Prinzip nur ein Konsolenprogramm starten und zu einem späteren Zeitpunkt wieder stoppen können. Die Konsole wird später gar nicht erst angezeigt, sondern soll unsichtbar im Hintergrund laufen.

Ich habe auch schon versucht ein Ctrl+C an die Konsole zu schicken aber das hat auch nicht den gewünschten Effekt gebracht:
Delphi-Quellcode:
PostMessage(ShExecInfo.hProcess, WM_KEYDOWN, VK_CONTROL, 0);
PostMessage(ShExecInfo.hProcess, WM_KEYDOWN, VkKeyScan('c'), 0);
PostMessage(ShExecInfo.hProcess, WM_KEYUP, VkKeyScan('c'), 0);
PostMessage(ShExecInfo.hProcess, WM_KEYUP, VK_CONTROL, 0);
  Mit Zitat antworten Zitat
shebang
Online

Registriert seit: 7. Feb 2020
97 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: ShellExecuteEx + TerminateProcess

  Alt 22. Apr 2021, 14:40
Bist du sicher, dass der Prozess nicht beendet wird? Du killst cmd.exe, aber die Ausgabe kommt von ping.exe. Führt man eine CMD von Hand aus (mit ping auf irgendeinen Host) und killt per Task-Manager die cmd.exe, bleibt das Konsolenfenster dennoch offen und wird erst bei Abbruch der ping.exe (z.B. per Strg+C) geschlossen.
Komme ich denn irgendwie an das Handle von ping.exe, damit ich dem ein Strg+C schicken kann?
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.415 Beiträge
 
Delphi 7 Professional
 
#7

AW: ShellExecuteEx + TerminateProcess

  Alt 22. Apr 2021, 15:41
Was passiert denn bei
Delphi-Quellcode:
 ShExecInfo.cbSize := SizeOf(ShellExecuteInfo);
  ShExecInfo.fMask := SEE_MASK_NOCLOSEPROCESS;
  ShExecInfo.lpVerb := 'open';
  ShExecInfo.lpFile := 'ping.exe';
  ShExecInfo.lpParameters := '-t delphipraxis.net';
  ShExecInfo.nShow := SW_SHOW;
Brauchst Du denn überhaupt eine Konsole als "Zwischenwirt"?
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.110 Beiträge
 
Delphi 10 Seattle Enterprise
 
#8

AW: ShellExecuteEx + TerminateProcess

  Alt 22. Apr 2021, 16:00
Das kann hinten und vorne nicht klappen.
Erstens machst du PostMessage mit einem Handle auf den Prozess. Man schickt aber Messages an ein Fensterhandle (HWND).

Zweitens interessieren sich Konsolenanwendungen herzlich wenig für Messages.

Ich bleibe dabei, ich sehe zwei Möglichkeiten:
1. Man verbindet sich mit der Konsole des gestarteten Prozesses und schickt ihm ein Ctrl+C mittels GenerateConsoleCtrlEvent

oder

2. Man packt das Ding in einem Job und wenn man es wirklich hart abschießenb will schließt man einfach den Job.


Ich nutze unter Windows die Jobs gerne, sie funktionieren zuverlässig und sind wirklich das Mittel der Wahl wenn man selbst gestartete Prozesse ordentlich und sicher verwalten will.
  Mit Zitat antworten Zitat
shebang
Online

Registriert seit: 7. Feb 2020
97 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: ShellExecuteEx + TerminateProcess

  Alt 22. Apr 2021, 16:48
Was passiert denn bei
Delphi-Quellcode:
 ShExecInfo.cbSize := SizeOf(ShellExecuteInfo);
  ShExecInfo.fMask := SEE_MASK_NOCLOSEPROCESS;
  ShExecInfo.lpVerb := 'open';
  ShExecInfo.lpFile := 'ping.exe';
  ShExecInfo.lpParameters := '-t delphipraxis.net';
  ShExecInfo.nShow := SW_SHOW;
Brauchst Du denn überhaupt eine Konsole als "Zwischenwirt"?
Dein Vorschlag funktioniert prinzipiell, TerminateProcess beendet den Prozess wie gewünscht. Allerdings ist dann die Umleitung der Ausgabe in eine Datei nicht möglich.
  Mit Zitat antworten Zitat
Delphi.Narium

Registriert seit: 27. Nov 2017
2.415 Beiträge
 
Delphi 7 Professional
 
#10

AW: ShellExecuteEx + TerminateProcess

  Alt 22. Apr 2021, 17:06
Wieso nicht?
Delphi-Quellcode:
ShExecInfo.cbSize := SizeOf(ShellExecuteInfo);
ShExecInfo.fMask := SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.lpVerb := 'open';
ShExecInfo.lpFile := 'ping.exe';
ShExecInfo.lpParameters := '-t delphipraxis.net > c:\temp\datei_in_die_umgeleitet_werden.soll';
ShExecInfo.nShow := SW_SHOW;
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


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:50 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