2011-01-10 9 views
55

Ich bin auf der Suche nach einer Möglichkeit, ein Stück Code auszulösen, wenn eine Konsole Anwendung manuell geschlossen wird (Benutzer Fenster schließt). Versucht mit:"On Exit" für eine Konsolenanwendung

AppDomain.CurrentDomain.ProcessExit += 
    new EventHandler(CurrentDomain_ProcessExit); 

aber das obige funktioniert nicht, wenn manuell geschlossen.

Gibt es irgendwelche Möglichkeiten, einen .Net-Aufruf dafür zu verwenden, oder muss ich die Kernel-DLL importieren und tun Sie es so?

+2

Bedeuten Sie mit "manuell schließen", dass der Benutzer auf das "Fenster schließen" -Kreuz in der oberen rechten Ecke des Konsolenfensters klickt? –

+0

Ich vermute, was Sie suchen, ist die "On Exit" der Befehlszeile selbst .. Sobald die 'Main' Methode der Konsolenanwendung erfolgt ist, ist es außerhalb Ihrer Kontrolle und Benutzer müssen die Eingabetaste drücken, um zu schließen das Befehlszeilenfenster. –

+0

@Martin. Ja das ist, was ich meinte. Wird zur Klärung aktualisiert. – BlueVoodoo

Antwort

92

Dieser Code funktioniert der Benutzer schließt das Konsolenfenster zu fangen:

using System; 
using System.Runtime.InteropServices; 

class Program { 
    static void Main(string[] args) { 
     handler = new ConsoleEventDelegate(ConsoleEventCallback); 
     SetConsoleCtrlHandler(handler, true); 
     Console.ReadLine(); 
    } 

    static bool ConsoleEventCallback(int eventType) { 
     if (eventType == 2) { 
      Console.WriteLine("Console window closing, death imminent"); 
     } 
     return false; 
    } 
    static ConsoleEventDelegate handler; // Keeps it from getting garbage collected 
    // Pinvoke 
    private delegate bool ConsoleEventDelegate(int eventType); 
    [DllImport("kernel32.dll", SetLastError = true)] 
    private static extern bool SetConsoleCtrlHandler(ConsoleEventDelegate callback, bool add); 

} 

der Einschränkungen Vorsicht. Sie haben, um schnell auf diese Benachrichtigung zu reagieren, haben Sie 5 Sekunden, um die Aufgabe abzuschließen. Nehmen Sie länger und Windows wird Ihren Code ohne Umschweife töten. Und Ihre Methode wird in einem Worker-Thread asynchron aufgerufen. Der Status des Programms ist völlig unvorhersehbar, sodass eine Sperre wahrscheinlich erforderlich ist. Stellen Sie unbedingt sicher, dass ein Abbruch keine Probleme verursachen kann. Wenn Sie beispielsweise den Status in eine Datei speichern, stellen Sie sicher, dass Sie zuerst in einer temporären Datei speichern und File.Replace() verwenden.

+0

Das ist sehr gut zu wissen. Darf muss das umgehen. Danke für deine Antwort. Verbessere deine Antwort +1. – BlueVoodoo

+3

Funktioniert gut! Wenn jemand an den anderen möglichen Ereignistypen interessiert ist: http://msdn.microsoft.com/en-us/library/ms683242%28v=vs.85%29.aspx –

+0

Speichern in eine temporäre Datei ist zuerst ein sehr guter Tipp. Es ist nicht nur sicher gegen die Anwendung plötzlich geschlossen, sondern auch das System. es ist so einfach. Genau das, was ich gesucht habe +1 – symbiont

Verwandte Themen