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 anderen Prozess beenden und löschen (https://www.delphipraxis.net/99401-anderen-prozess-beenden-und-loeschen.html)

Master-of-Magic 11. Sep 2007 19:13


anderen Prozess beenden und löschen
 
Ich möchte einen anderen Prozess beenden (im Notfall erzwingen) und danach dessen .exe löschen (ebenfalls erzwingen). Das zu löschende Programm befindet sich im selben Verzeichnis, wie das ausführende Programm. Folgender Code liefert mir "Zugriff verweigert":

Delphi-Quellcode:
KillTask('Tool.exe');
DeleteFile(ExtractFileDir(ParamStr(0)) + '\Tool.exe');
mit
Delphi-Quellcode:
function TForm1.KillTask(ExeFileName: string): Integer;
const
  PROCESS_TERMINATE = $0001;
var
  ContinueLoop: BOOL;
  FSnapshotHandle: THandle;
  FProcessEntry32: TProcessEntry32;
begin
  Result := 0;
  FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
  ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);

  while Integer(ContinueLoop) <> 0 do
  begin
    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) =
      UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) =
      UpperCase(ExeFileName))) then
      Result := Integer(TerminateProcess(
                        OpenProcess(PROCESS_TERMINATE,
                                    BOOL(0),
                                    FProcessEntry32.th32ProcessID),
                                    0));
     ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
  end;
  CloseHandle(FSnapshotHandle);
end;
Der KillTask funktioniert soweit - wobei ich nicht weiß, ob das die beste Lösung ist. Das Löschen schlägt allerdings fehl, da Windows anscheinend noch eine Sekunde auf die Datei zugreift.
Wenn ich ein sleep(1000) einfüge oder der Prozess nicht läuft, klappt auch das Löschen!

Gibt's einfache Alternativen zu DeleteFile? Oder kann ich das irgendwie ohne sleep lösen?

SirThornberry 11. Sep 2007 19:25

Re: anderen Prozess beenden und löschen
 
Was ist der Sinn des ganzen? Vielleicht gibt es ja ein Workarround. Wird die andere Anwendung welche gelöscht werden soll durch dich gestartet? Und warum muss die Datei überhaupt gelöscht werden?

Master-of-Magic 11. Sep 2007 19:45

Re: anderen Prozess beenden und löschen
 
Es handelt sich um einen Updater der vor dem Update prüft, ob die Lizenz gültig ist. Ist dies nicht der Fall, darf das Tool nicht genutzt werden. Daher möchte ich eventuell noch laufende Instanzen beenden und das Tool danach löschen, damit der Nutzer zur Registrierung oder wenigstens zu einer Mail gezwungen wird.

Die andere Anwendung ist also nicht zwingend gestartet und wenn, dann durch den Benutzer ...

Luckie 11. Sep 2007 20:21

Re: anderen Prozess beenden und löschen
 
Nur so nebenbei:
Delphi-Quellcode:
while Integer(ContinueLoop) <> 0 do
Was ist denn das für eine Konstruktion? Warum nicht:
Delphi-Quellcode:
while ContinueLoop do
Ich sehen diesen Code immer und immer wieder wieder und er wid anscheinend immer und immer wieder ohne Sinn und Verstand kopiert. :?

Master-of-Magic 11. Sep 2007 21:06

Re: anderen Prozess beenden und löschen
 
Zitat:

Zitat von Luckie
Ich sehen diesen Code immer und immer wieder wieder und er wird anscheinend immer und immer wieder ohne Sinn und Verstand kopiert. :?

Ja, da hast du auch vollkommen Recht. Du hast diesen Hinweis ja auch bereits mehrfach woanders gepostet. Allerdings wollte ich mich erstmal um das andere Problem kümmern, bevor das KillProccess überarbeitet wird. :roll:

Der Grund für das Kopieren ist einfach: Man sucht eine Funktion und quält die Forensuche damit (meist hier und im Delphi-Forum). Dabei kommen massenhaft Threads raus, in denen wieder auf andere Threads oder die Suche verwiesen wird und irgendwann landet man in eines Diskussion über die Vor- und Nachteile einer Funktionsvariante. Oft gibt's dann Einschränkungen bei den Betriebssystemen.
Und regelmäßig wird auf eine Codesammlung (hier eben die Schweitzer) verwiesen, wo es "super-tolle Fertiglösungen" gibt. Was macht man also? Man nimmt den Schnipsel, der anscheinend von dem meisten verwendet wird oder der am kürzesten ist. Und da die meisten Leute wie auch ich bei den komplexeren Dingen (wo der hier schon fast dazugehört) nicht mehr viel verstehen, lassen sie den Code, wie er ist ...


Wenn du mir eine bessere Lösung zeigen kannst: Ich bin für alles offen. :coder2:
Ich hab mir auch schon überlegt, ob ich irgendwie eine Close-Message schicken und im anderen Tool behandeln kann (das ist auch von mir). Allerdings hab ich von Messages wieder keine Ahnung und das Herausfinden des Handles erscheint mir auch unverhältnismäßig aufwendig zu sein.

Sunlight7 11. Sep 2007 23:39

Re: anderen Prozess beenden und löschen
 
Moin!

Nur weil viele Leute den Code verwenden sagt das noch lange nichts über die Qualität aus.

Was machst Du, wenn der Nutzer ein anderes Programm mit dem Dateinamen "Tool.exe" am laufen hat? :shock:
Das killst Du dann auch... :stupid:

Schau Dich mal nach Hier im Forum suchenDDE um, oder gib Deinem Fenstern sehr eindeutige Namen und suche es mit Hier im Forum suchenFindWindow.
Somit kannst Du eine eigene Nachricht mit Hier im Forum suchenSendMessage zum schließen senden.

Master-of-Magic 13. Sep 2007 18:35

Re: anderen Prozess beenden und löschen
 
Naja, DDE wäre in dem Fall wirklich zuviel des Guten. Und FindWindow benötigt afaik die genaue Fenstercaption - und ist nicht vorhersagbar ... :(

Sunlight7 13. Sep 2007 18:40

Re: anderen Prozess beenden und löschen
 
Zitat:

Zitat von Master-of-Magic
Naja, DDE wäre in dem Fall wirklich zuviel des Guten. Und FindWindow benötigt afaik die genaue Fenstercaption - und ist nicht vorhersagbar ... :(

Warum?

Gut, DDE muß net sein, aber mach ein zusätzliches verstecktes Fenster mit einem eindeutigem Titel, zB: "Das ist mein zu findendes Fenster von meinem super coolem Programm names: Platziere Deinen Programmnamen hier" :mrgreen:

Master-of-Magic 16. Sep 2007 19:19

Re: anderen Prozess beenden und löschen
 
Ok, da es scheinbar keinen 'sauberen' Weg gibt, hab ich die Sache jetzt anders gelöst:

Beide Programme registrieren über RegisterWindowMessage() eine bestimmte Message WM_BLA. Das zu beendende Programm fängt diese ab und handelt entsprechend.

Der Updater schickt dann nur noch diese Message über
Delphi-Quellcode:
SendNotifyMessage(FindWindow(PChar('TKlassenname'), nil), WM_BLA, 0, 0);
Das halte ich für die sauberste Lösung, die auch auf allen Systemen funktionieren sollte. Löschen muss ich die Datei nicht mehr, da diese beim nächsten Start aufgrund der gelöschten Lizenzinfos sowieso die Arbeit verweigert ...
Und falls zufällig ein anderes Programm den gleichen Klassennamen verwendet, wird es bestimmt nicht auf WM_BLA reagieren.

Hat sich also doch gelohnt, sich Messages mal anzuschauen ... :mrgreen:


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