2011-01-10 15 views
55

Estoy buscando una forma de activar un fragmento de código cuando una aplicación de consola se cierra manualmente (los usuarios cierran la ventana). He estado intentando con:"Al salir" para una aplicación de consola

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

pero lo anterior no funciona si se cierra manualmente.

¿Hay alguna forma de utilizar una llamada .Net para esto o necesito importar el dll Kernel y hacerlo de esa manera?

+2

¿Al hacer "cerrar manualmente" significa que el usuario hace clic en la cruz de "cerrar ventana" en la esquina superior derecha de la ventana de la consola? –

+0

Sospecho que lo que busca es "Al salir" de la línea de comandos ... tan pronto como se complete el método 'Principal 'de la aplicación de la consola, está fuera de su control y el usuario debe presionar la tecla Entrar para cerrar la ventana de línea de comando. –

+0

@Martin. Sí, eso es lo que quise decir. Se actualizará para aclaración. – BlueVoodoo

Respuesta

92

Este código funciona para atrapar al usuario cerrar la ventana de la consola:

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

} 

Cuidado con las restricciones. Usted tiene para responder rápidamente a esta notificación, tiene 5 segundos para completar la tarea. Tómate más tiempo y Windows matará tu código sin ceremonias. Y su método se llama asíncronamente en un hilo de trabajo, el estado del programa es completamente impredecible, por lo que es probable que sea necesario bloquearlo. Asegúrese de que un aborto no cause problemas. Por ejemplo, al guardar el estado en un archivo, asegúrese de guardar primero en un archivo temporal y use File.Replace().

+0

Eso es muy bueno saberlo. Puede tener que trabajar alrededor de eso. Gracias por su respuesta. Alzando tu respuesta +1. – BlueVoodoo

+3

¡Funciona muy bien! Si alguien está interesado en los otros posibles tipos de eventos: http://msdn.microsoft.com/en-us/library/ms683242%28v=vs.85%29.aspx –

+0

guardar primero en un archivo temporal es una muy buena sugerencia. no solo es seguro contra el cierre repentino de la aplicación, sino también el sistema. Es tan simple. justo lo que estaba buscando +1 – symbiont

Cuestiones relacionadas