2011-01-10 23 views
55

Szukam sposobu wyzwalania fragmentu kodu, gdy aplikacja konsoli jest ręcznie zamykana (użytkownicy zamykają okno). Próbowałem z:"Przy wyjściu" dla aplikacji konsolowej

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

, ale powyższe nie działa, gdy jest ręcznie zamknięty.

Czy są jakieś sposoby na wywołanie funkcji .Net w tym celu lub czy muszę zaimportować bibliotekę jądra Kernela i zrobić to w ten sposób?

+2

Czy przez "ręczne zamykanie" oznacza, że ​​użytkownik klika krzyżyk "zamknij okno" w prawym górnym rogu okna konsoli? –

+0

Podejrzewam, że to, o co prosisz, to "On Exit" samej linii komend .. jak tylko zostanie wykonana metoda 'Main' aplikacji konsoli, to jest poza twoją kontrolą i użytkownik musi nacisnąć klawisz Enter, aby zamknąć okno wiersza poleceń. –

+0

@Martin. Tak, właśnie o to mi chodziło. Zostanie zaktualizowany w celu wyjaśnienia. – BlueVoodoo

Odpowiedz

92

Ten kod działa złapać użytkownikowi zamykając okno konsoli:

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); 

} 

Strzeż ograniczeń. Musisz mieć, aby szybko odpowiedzieć na to powiadomienie, masz 5 sekund na wykonanie zadania. Zaczekaj dłużej, a Windows zabije Twój kod bezceremonialnie. A twoja metoda jest asynchronicznie na wątku roboczym, stan programu jest całkowicie nieprzewidywalny, więc blokowanie będzie prawdopodobnie wymagane. Upewnij się, że przerywanie nie może powodować problemów. Na przykład, zapisując stan do pliku, upewnij się, że najpierw zapisałeś w pliku tymczasowym i użyłeś File.Replace().

+0

To bardzo dobrze wiedzieć. Może to obejdzie. Dzięki za odpowiedź. Upping your answer +1. – BlueVoodoo

+3

Działa świetnie! Jeśli ktoś interesuje się innymi możliwymi typami zdarzeń: http://msdn.microsoft.com/en-us/library/ms683242%28v=vs.85%29.aspx –

+0

zapisywanie do pliku tymczasowego jako pierwsze jest bardzo dobrą wskazówką. jest nie tylko bezpieczny w przypadku zamknięcia aplikacji, ale także w systemie. to takie proste. Właśnie to, czego szukałem +1 – symbiont

Powiązane problemy