Delphi-PRAXiS
Seite 3 von 5     123 45      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Klasse zum Beenden eines Prozesses (https://www.delphipraxis.net/156073-klasse-zum-beenden-eines-prozesses.html)

Basilikum 21. Nov 2010 08:29

AW: Klasse zum Beenden eines Prozesses
 
irgendwie vermisse ich noch an geeigneter Stelle ein
Delphi-Quellcode:
FProcessID:=0;
, sonst kann die Konstallation eintreten, dass willkürlich ein Prozess terminiert wird (Prozess nicht gefunden, FProcessID steht zufällig auf einem Wert, der ein existierenden Prozess bezeichnet).

toms 21. Nov 2010 09:29

AW: Klasse zum Beenden eines Prozesses
 
Es ist ja bekannt, dass TerminateProcess() einen Prozess nicht unbedingt ordnungsgemäß beendet.
Darum werfe ich die Funktion SafeTerminateProcess vom Artikel A Safer Alternative to TerminateProcess() auf Dr. Dobb's in den Raum.

Siehe auch eine Delphi Umsetzung.

Anbei noch 2 Funktionen zum Überprüfen, ob ein Prozess beendet wurde:
  • GetExitCodeProcess()
  • if not CloseHandle() then ..;

Sir Rufo 21. Nov 2010 10:26

AW: Klasse zum Beenden eines Prozesses
 
Irgendwie verstehe ich nicht, warum das hier in eine Klasse gegossen wird.
Eine schnöde function/procedure hätte es auch getan.

Aber nun erzeuge ich eine Instanz um eine andere Instanz zu beenden und dann beende ich diese Beende-Instanz. Klingt irgendwie nicht logisch.

Was für mich Sinn ergeben würde, wäre eine Klasse, die zu einem Prozess Informationen gibt.
Wieviele Instanzen sind aktiv, wie hoch ist der Speicherverbrauch, etc.
Ja, die Möglichkeit einen Prozess zu killen gehört da auch rein.

Als Events würden sich anbieten, wenn einen neue Instanz auftaucht und wenn eine Instanz verschwindet.

Dann würde sich auch eine Klasse rechtfertigen.

Wäre also eine TaskManagerKlasse für jeweils eine Anwendung.

Assarbad 21. Nov 2010 10:37

AW: Klasse zum Beenden eines Prozesses
 
Zitat:

Zitat von toms (Beitrag 1062963)
Darum werfe ich die Funktion SafeTerminateProcess vom Artikel A Safer Alternative to TerminateProcess() auf Dr. Dobb's in den Raum.

Ähem, das ist Mumpitz, oder? Denn erstens braucht man mindestens die gleichen Rechte wie für TerminateProcess und zweitens wird diese Methode hier nicht zwischen Sitzungen funktionieren (Vista aufwärts). Sagen wir mal so, mit einem Datum von 1999 ist der Code mehr oder weniger "abgelaufen".

toms 21. Nov 2010 11:03

AW: Klasse zum Beenden eines Prozesses
 
Zitat:

Zitat von Assarbad (Beitrag 1062986)
Zitat:

Zitat von toms (Beitrag 1062963)
Darum werfe ich die Funktion SafeTerminateProcess vom Artikel A Safer Alternative to TerminateProcess() auf Dr. Dobb's in den Raum.

Ähem, das ist Mumpitz, oder? Denn erstens braucht man mindestens die gleichen Rechte wie für TerminateProcess und zweitens wird diese Methode hier nicht zwischen Sitzungen funktionieren (Vista aufwärts). Sagen wir mal so, mit einem Datum von 1999 ist der Code mehr oder weniger "abgelaufen".

Die Grundidee ist noch nicht "abgelaufen". Die Methode mit "CreateRemoteThread, ExitProcess" wird nebst 13 anderen von "Process Hacker" implementiert und auch bei MySQL zu finden.

Luckie 21. Nov 2010 12:03

AW: Klasse zum Beenden eines Prozesses
 
Zitat:

Zitat von Sir Rufo (Beitrag 1062978)
Irgendwie verstehe ich nicht, warum das hier in eine Klasse gegossen wird.
Eine schnöde function/procedure hätte es auch getan.

Es ist eben nicht nur eine Funktion, sondern mindestens zwei, wenn man den Prozess über den Dateinamen beenden will. Da diese zusammen gehören, bietet sich eine Klasse an.

Zitat:

Aber nun erzeuge ich eine Instanz um eine andere Instanz zu beenden und dann beende ich diese Beende-Instanz. Klingt irgendwie nicht logisch.
Falls du die Klasse TMain meinst, die wird in der Konsolenanwendung nur benötigt, wegen des Ereignisses.

Zitat:

Was für mich Sinn ergeben würde, wäre eine Klasse, die zu einem Prozess Informationen gibt.
Wieviele Instanzen sind aktiv, wie hoch ist der Speicherverbrauch, etc.
Das wäre eine andere Baustelle.
Zitat:

Ja, die Möglichkeit einen Prozess zu killen gehört da auch rein.
Meiner Meinung nach nicht, da das Ermitteln von Informationen und das Beenden eines Prozesses zwei unterschiedliche Aufgaben sind.

@Toms: Richtig mittels GetExitCodeProzess könnte ich bei einem TimeOut von 0 Millisekunden prüfen, ob der Prozess beendet wurde.

Sir Rufo 21. Nov 2010 13:21

AW: Klasse zum Beenden eines Prozesses
 
Man muss eine Instanz von
Delphi-Quellcode:
TKillProcess
erzeugen um eine andere Instanz zu beenden.
Das halte ich für unlogisch.

Mit der Klasse
Delphi-Quellcode:
TKillProcess
fragst du eh schon die Eigenschaften des Prozesses ab, weil du ja zu einem ExeNamen die ProcessID ermitteln möchtest.

Für mich würde die Klasse nur dann einen Sinn ergeben, wenn die Klasse eine längere Daseinsberechtigung als nur zum reinen Killen des Prozesses.

Eine Möglichkeit wäre es doch erst beim Aufrufen der Methode Kill die ProcessID zu ermitteln und dann zu killen.

Dann erzeugt man sich die Klasse, gibt den ExeNamen an und immer wenn man diese Exe aus dem Speicher haben möchte ruft man einfach Kill auf und die Prozesse werden gelöscht.

Das vermisse ich auch irgendwie, wenn eine Anwendung n-fach gestartet wurde, dann wird nur eine gelöscht. Welche das ist, hängt davon ab, welche als letzte in der Prozess-Liste steht.
Somit würde ich erwarten, dass bei der Angabe eines ExeNamens alle Prozesse gelöscht werden, die dazu gehören.

Dann wäre das Verhalten auch eindeutig und nicht ein Zufallsprodukt.

Ei Argument, was noch gegen die Verwendung einer Klasse spricht ist, dass es bei dem jetzigen Aufbau zu Fehlern kommen kann, die man so eigentlich nicht haben will.

Delphi-Quellcode:
KP := TKillProcess.Create;
try
  KP.FileName := 'notepad++.exe'; // Jetzt ermittelt die Klasse die PID
 
  // Ich muss jetzt noch ein paar Sachen prüfen, die so eine gewisse Zeit dauern
  Sleep( 10000 ); // So als Dummy-Beschäftigung

  KP.Kill; // Ja, ist denn die PID von eben immer noch die richtige?
 
finally
  KP.Free;
end;
Dieses ist durch dein Design so möglich und kann dazu führen, dass

a) Der Prozess ist schon beendet worden (von wem auch immer)
Wenn Kill jetzt einen Fehler wirft, ist der Fehler dann nicht verwirrend.
Ich möchte das als Resultat der Prozess nicht mehr im System läuft.
Das ist ja auch erreicht worden (zwar nicht ursächlich durch die Klasse, aber das Resultat ist das Gleiche) aber ich bekomme einen Fehler.
Könnte man evtl. noch mit leben

b) Der Prozess ist schon beendet worden( von wem auch immer) und ein völlig anderer Prozess (z.B. outlook.exe) hat jetzt die gleiche PID bekommen wie notepad++.exe vorher hatte. Nun wird mit Kill nicht notepad++.exe sondern outlook.exe geschlossen

Assarbad 21. Nov 2010 14:44

AW: Klasse zum Beenden eines Prozesses
 
Zitat:

Zitat von toms (Beitrag 1063000)
Die Grundidee ist noch nicht "abgelaufen". Die Methode mit "CreateRemoteThread, ExitProcess" wird nebst 13 anderen von "Process Hacker" implementiert und auch bei MySQL zu finden.

Wobei Process Hacker für mich nicht das Maß der Dinge ist :lol:

Ich sage nur, daß es ab Vista größere Probleme aufgrund der Sitzungsisolation und der Integritätsniveaus kommen wird. Ob und/oder wie das beherzigt wird, ist mir an Ende egal :zwinker:

Luckie 21. Nov 2010 15:10

AW: Klasse zum Beenden eines Prozesses
 
Zitat:

Zitat von Sir Rufo (Beitrag 1063048)
Man muss eine Instanz von
Delphi-Quellcode:
TKillProcess
erzeugen um eine andere Instanz zu beenden.
Das halte ich für unlogisch.

Ein Prozess ist mich keine Instanz.

Zitat:

Für mich würde die Klasse nur dann einen Sinn ergeben, wenn die Klasse eine längere Daseinsberechtigung als nur zum reinen Killen des Prozesses.
Für mich hat eine Klasse schon dann eine Daseinsberechtigung, wenn sie mehrere zusammen gehörende Routinen kapselt.

Zitat:

Eine Möglichkeit wäre es doch erst beim Aufrufen der Methode Kill die ProcessID zu ermitteln und dann zu killen.
Das wäre eine Möglichkeit, die es sich lohnt noch mal zu überdenken. Aber selbst dann hast du, wenn du sauber programmieren willst mindestens zwei Routinen.
Zitat:

Dann erzeugt man sich die Klasse, gibt den ExeNamen an und immer wenn man diese Exe aus dem Speicher haben möchte ruft man einfach Kill auf und die Prozesse werden gelöscht.
Das ergibt Sinn.

Zitat:

Das vermisse ich auch irgendwie, wenn eine Anwendung n-fach gestartet wurde, dann wird nur eine gelöscht. Welche das ist, hängt davon ab, welche als letzte in der Prozess-Liste steht.
Somit würde ich erwarten, dass bei der Angabe eines ExeNamens alle Prozesse gelöscht werden, die dazu gehören.

Dann wäre das Verhalten auch eindeutig und nicht ein Zufallsprodukt.
Dann müsste ich nach dem Beenden die Prozessliste immer wieder durchlaufen. Mal gucken, wie sich das realisieren lässt.

Ei Argument, was noch gegen die Verwendung einer Klasse spricht ist, dass es bei dem jetzigen Aufbau zu Fehlern kommen kann, die man so eigentlich nicht haben will.

Zitat:

Delphi-Quellcode:
KP := TKillProcess.Create;
try
  KP.FileName := 'notepad++.exe'; // Jetzt ermittelt die Klasse die PID
 
  // Ich muss jetzt noch ein paar Sachen prüfen, die so eine gewisse Zeit dauern
  Sleep( 10000 ); // So als Dummy-Beschäftigung

  KP.Kill; // Ja, ist denn die PID von eben immer noch die richtige?
 
finally
  KP.Free;
end;
Dieses ist durch dein Design so möglich und kann dazu führen, dass

a) Der Prozess ist schon beendet worden (von wem auch immer)
Wenn Kill jetzt einen Fehler wirft, ist der Fehler dann nicht verwirrend.
Ich möchte das als Resultat der Prozess nicht mehr im System läuft.
Das ist ja auch erreicht worden (zwar nicht ursächlich durch die Klasse, aber das Resultat ist das Gleiche) aber ich bekomme einen Fehler.
Könnte man evtl. noch mit leben

b) Der Prozess ist schon beendet worden( von wem auch immer) und ein völlig anderer Prozess (z.B. outlook.exe) hat jetzt die gleiche PID bekommen wie notepad++.exe vorher hatte. Nun wird mit Kill nicht notepad++.exe sondern outlook.exe geschlossen
Dann setze den Prozessnamen nach dem Code:
Delphi-Quellcode:
KP := TKillProcess.Create;
try
  // Ich muss jetzt noch ein paar Sachen prüfen, die so eine gewisse Zeit dauern
  Sleep( 10000 ); // So als Dummy-Beschäftigung

  KP.FileName := 'notepad++.exe'; // Jetzt ermittelt die Klasse die PID
  KP.Kill; // Ja, ist denn die PID von eben immer noch die richtige?
 
finally
  KP.Free;
end;

Sir Rufo 21. Nov 2010 15:23

AW: Klasse zum Beenden eines Prozesses
 
Hmmm, wenn man eine Klasse nur dann korrekt benutzen kann, indem man x Vorgaben einhält, und diese Vorgaben aber nur durch ein ungeschicktes Design der Klasse herrühren, dann würde ich immer das Design der Klasse ändern.

Ansonsten muss man an solche Klassen immer den Hinweis kleben:
Zitat:

Ask the old and wise before use!
Da gab es vor kurzem ein sehr geiles Video genau zu diesem Thema, mal sehen ob ich den Link dazu noch finde. War irgendwas mit Singletons.

Hier der Beitrag mit dem Link zum Video

Prozess und Instanz

Wenn eine Anwendung x-fach gestartet ist, und man findet somit im System auch x Prozesse, so kann man im übertragenen Sinne auch von Instanzen sprechen.
Ich wollte damit nur sprachlich darstellen, dass hier etwas erzeugt wird um etwas anderes zu zerstören und dann muss ich diesen Zerstören selber wieder zerstören, weil dieser nutzlos geworden ist (es sei denn ich weise diesem wieder einen neuen Wert zu)


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:47 Uhr.
Seite 3 von 5     123 45      

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