![]() |
ShellExecuteEx + TerminateProcess
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:
Das Flag
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;
Delphi-Quellcode:
führt dazu, dass das Process handle in der Variablen
SEE_MASK_NOCLOSEPROCESS
Delphi-Quellcode:
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?
ShExecInfo.hProcess
PS: CreateProcess verwende ich nicht, da dort die Umleiten der Ausgabe in eine Datei nicht funktioniert. |
AW: ShellExecuteEx + TerminateProcess
Der Doku "
![]() Zitat:
![]() 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 ![]() |
AW: ShellExecuteEx + TerminateProcess
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 |
AW: ShellExecuteEx + TerminateProcess
![]() ![]() ![]() Aber ja, wenn es ein anderes Programm ausführt bringt das nicht viel.... |
AW: ShellExecuteEx + TerminateProcess
Zitat:
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); |
AW: ShellExecuteEx + TerminateProcess
Zitat:
|
AW: ShellExecuteEx + TerminateProcess
Was passiert denn bei
Delphi-Quellcode:
Brauchst Du denn überhaupt eine Konsole als "Zwischenwirt"?
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; |
AW: ShellExecuteEx + TerminateProcess
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 ![]() 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. |
AW: ShellExecuteEx + TerminateProcess
Zitat:
|
AW: ShellExecuteEx + TerminateProcess
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; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:40 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