2011-01-10 12 views
55

Sto cercando un modo per attivare una parte di codice quando un'applicazione console viene chiusa manualmente (gli utenti chiudono la finestra). Provato con:"On Exit" per un'applicazione console

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

ma quanto sopra non funziona se chiuso manualmente.

C'è qualche modo per utilizzare una chiamata .Net per questo o devo importare la DLL del kernel e farlo in quel modo?

+2

"chiudendo manualmente" significa che l'utente fa clic sulla croce "finestra chiusa" nell'angolo in alto a destra della finestra della console? –

+0

Sospetto che quello che stai cercando sia "On Exit" della riga di comando stessa ... non appena il metodo 'Main' dell'applicazione della console è terminato, è fuori dal tuo controllo e l'utente deve premere il tasto Invio per chiudere la finestra della riga di comando. –

+0

@ Martin. Sì, questo è quello che intendevo. Aggiornerà per chiarimenti. – BlueVoodoo

risposta

92

Questo codice funziona per catturare l'utente di chiudere la finestra di console:

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

} 

Attenzione delle restrizioni. Tu hai per rispondere rapidamente a questa notifica, hai 5 secondi per completare l'operazione. Prendi più tempo e Windows ucciderà il tuo codice senza troppe cerimonie. E il tuo metodo è chiamato in modo asincrono su un thread di lavoro, lo stato del programma è del tutto imprevedibile, quindi è probabile che il blocco sia richiesto. Assicurati assolutamente che l'interruzione non possa causare problemi. Ad esempio, quando si salva lo stato in un file, assicurarsi di salvare prima un file temporaneo e utilizzare File.Replace().

+0

Questo è molto bello sapere. Potrebbe essere necessario aggirare questo problema. Grazie per la tua risposta. Upping your answer +1. – BlueVoodoo

+3

Funziona alla grande! Se qualcuno è interessato agli altri possibili tipi di eventi: http://msdn.microsoft.com/en-us/library/ms683242%28v=vs.85%29.aspx –

+0

salvare prima in un file temporaneo è un ottimo consiglio. non è solo sicuro contro l'applicazione che si chiude all'improvviso, ma anche sul sistema. è così semplice proprio quello che stavo cercando +1 – symbiont