Frage

Wie kann ich Ressourcen freigeben, wenn der Prozess durch zum Beispiel des Task-Manager getötet wird? Gibt es eine Möglichkeit, eine Funktion aufzurufen, bevor der Prozess geschlossen wird?

War es hilfreich?

Lösung

Es gibt wirklich nichts, was Sie tun können, wenn Ihr Prozess abgebrochen wird. Per Definition ist ein Prozess zu töten, dass nur - töten sie. Der Prozess wird nicht die Möglichkeit, beliebigen Code auszuführen. Das ist sehr viel „by design“.

Stellen Sie sich vor, dass Sie eine Routine registrieren könnten, die aufgerufen wurde, wenn der Prozess durch den Benutzer (oder von einem anderen Prozess) getötet wurde. Was würde es tun? Alle anderen Threads in Ihrem Prozess in einem unbestimmten Zustand wäre, wie würden Sie mit ihnen zu synchronisieren? Denken Sie daran, die Idee ist, dass der Prozess getötet werden muss.

Das andere Szenario ist noch härter: Ihr Code ist gutartig und versucht, das Richtige zu tun - zum Beispiel aufzuräumen und ein gutes System Bürger. Einige Code nicht. Stellen Sie sich vor, was ein Segen für Malware-Autor wäre es, wenn das Betriebssystem erlaubt Code für einen Prozess ausgeführt werden, die getötet wurde. Es wäre genug für schädliche Prozesse schlecht sein, die mit Standardbenutzerrechten ausgeführt wurden, und ganz schrecklich für jeden laufenden mit Administratorrechten an.

Critical finalisiert und die strukturierte Ausnahmebehandlung nicht dieses grundlegende Problem lösen.

Auf der anderen Seite wird frei, die OS alle Ressourcen, die sie kennt, wenn der Prozess abgebrochen wird, nämlich Speicher und Kernel-Objekte. Diese werden nicht auslaufen. Aber Explorer nicht weiß, über den Prozess, so dass es nicht für sie bereinigen kann.

Eine Möglichkeit, dies zu lösen wäre, einen Monitoring-Prozess zu haben, die den Überblick über Ihre anderen Prozessen Zustand hält und es aufräumt. Man könnte dies mit einem einfachen Verfahren, oder mit einem Service. Vielleicht haben Sie auch eine Art von Shell-Erweiterung betrachten, die einen eigenen Thread hatte, die das gleiche tat.

Andere Tipps

Es gibt keine Möglichkeit, beliebigen Code bei Beendigung auszuführen innerhalb eines Prozesses, der im Begriff ist, durch einen Aufruf getötet werden, um TerminateProcess, wie durch die Task-Manager oder einen anderen Prozess Dienstprogramm wie Tskill oder TASKKILL.

Weder kritische Finalizer, noch gewöhnlicher Finalizers, noch try / finally Blöcke, und schon gar nicht nur Objekte, die IDisposable implementieren kann Code verursachen in diesem Szenario ausgeführt werden. Auch DLL Ereignisse lösen werden nicht von einer Prozessbeendigung über TerminateProcess aufgerufen werden.

Das Beste, was Sie tun können, ist ein Watchdog-Prozess zu verwenden, die Ihre ursprüngliche Prozess überwacht und führt einen entsprechenden Code, wenn der ursprüngliche Prozess beendet wird.

Theoretisch die O / S sollten Ressourcen freigeben, nachdem der Prozess abgebrochen wird. Welche Art von Ressource denken Sie insbesondere?


Edit:

  

Ok, es ist irgendwie schwer zu erklären. Ich verwende eine Bibliothek, die einige der OS-Funktionen wickelt einige Shell-Erweiterungen zu verwalten. Wenn die Anwendung geschlossen wird, ohne explizit die entsprechenden Methoden aufrufen, die alle Explorer friert, und ich brauche, um es neu zu starten.

Jede nicht verwaltete DLL ist (entsprechend der Dokumentation) soll mit einem DLL_PROCESS_DETACH Ereignis aufgerufen werden; jedoch wird dieses DLL_PROCESS_DETACH Ereignis nicht aufgerufen, wenn der Prozess über die TerminateProcess API beendet wird.

Googeln für diese Begriffe aufgedreht The Old New Thing: Warum können Sie nicht Falle TerminateProcess die sagt: " Wenn Sie mit TerminateProcess töten, nicht mehr Benutzermodus-Code in diesem Prozess ausgeführt wird. Es ist weg. "

Weil alles, was Sie versuchen, mit zu arbeiten (das heißt .NET Explorer, Shell, COM) geschieht im User-Modus, ich denke, die Antwort ist, dass es keine Möglichkeit, zu tun, was Sie wollen.

Stattdessen vielleicht gibt es eine andere Art und Weise. B. durch Code in Ihre Shell-Erweiterungen hinzugefügt, so dass sie erkennen, wenn Ihr Prozess abnormal beendet wird

Sie könnten versuchen, Ihren gesamten Prozess in einer try / finally-Anweisung Einwickeln (Sie können die Aufhebung der Zuordnung Sachen in der finally-Klausel setzen), aber in einigen Fällen auch das wird nicht genug sein.

Eigentlich, denke ich Dir einen Hintergrund-Thread aus dem Prozess starten könntest die ganze Zeug und Thread.Join () mit dem Haupt-Thread zu tun, so dass, wenn etwas in dem Kind Faden schief geht, wird der Haupt-Thread noch in der Lage sein, bekommen die Dinge richtig. Natürlich wird dies nicht funktionieren, wenn der gesamte Prozess aus irgendeinem Grund beendet wird.

Sie können auch ein Kind-Prozess starten und rufen Process.WaitForExit (), aber ich bin mir nicht sicher, ob die Shell bezogene Sache mit einem Multi-Prozess-Ansatz funktionieren könnte.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top