2012-03-27 19 views
8

Estoy escribiendo una aplicación C# que necesita cargar un archivo cuando la consola está cerrada (ya sea con el botón X o la computadora se apaga).¿Ejecutar el código en la consola cerrada?

¿Cómo podría hacer esto?

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

sólo se ejecuta cuando emita el comando exit a la consola, no cuando pulso el botón de color rojo.

Solo responda si la solución se ejecuta tanto cuando la consola se cierra con el botón X, y cuando la computadora se apaga (normalmente a través de Windows, sé que no se puede si la energía se extrae xD).

+3

lo siento, dicen, pero hay situaciones donde el proceso se mata por lo que no puede conseguir que esto funcione en todos los casos posibles (tal vez lo has visto en Win7, donde se cierra y el sistema le dice que algunos procesos impiden el cierre y puede optar por terminarlos) – Carsten

+0

@ CarstenKönig Entiendo que hay situaciones como esa, pero quiero que al menos funcione bajo un proceso de apagado normal en el caso de que el el usuario no fuerza el cierre de las aplicaciones. –

+0

posible duplicado http://stackoverflow.com/questions/474679/capture-console-exit-c-sharp –

Respuesta

10

Usted tiene que invocar la API de Win32, para ello, basta con echar un vistazo a este post aquí http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/707e9ae1-a53f-4918-8ac4-62a1eddb3c4a/

He copiado el código correspondiente para que desde allí:

class Program 

{ 
    private static bool isclosing = false; 

    static void Main(string[] args) 
    { 
     SetConsoleCtrlHandler(new HandlerRoutine(ConsoleCtrlCheck), true); 

     Console.WriteLine("CTRL+C,CTRL+BREAK or suppress the application to exit"); 

     while (!isclosing) ; 
    } 

    private static bool ConsoleCtrlCheck(CtrlTypes ctrlType) 
    { 
     // Put your own handler here 

     switch (ctrlType) 
     { 
      case CtrlTypes.CTRL_CLOSE_EVENT: 
       isclosing = true; 
       Console.WriteLine("Program being closed!"); 
       break; 
     } 

     return true; 
    } 

    #region unmanaged 
    // Declare the SetConsoleCtrlHandler function 
    // as external and receiving a delegate. 

    [DllImport("Kernel32")] 
    public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add); 

    // A delegate type to be used as the handler routine 
    // for SetConsoleCtrlHandler. 
    public delegate bool HandlerRoutine(CtrlTypes CtrlType); 

    // An enumerated type for the control messages 
    // sent to the handler routine. 

    public enum CtrlTypes 
    { 
     CTRL_C_EVENT = 0, 
     CTRL_BREAK_EVENT, 
     CTRL_CLOSE_EVENT, 
     CTRL_LOGOFF_EVENT = 5, 
     CTRL_SHUTDOWN_EVENT 
    } 

    #endregion 
} 

Hace exactamente Que necesitas.

Saludos,

+0

¡Esto funciona perfectamente! –

0

Puede ser algo como esto (suponiendo que el derecho entendí que usted solicite)

//get all command windows in the system 
Process[] processes = Process.GetProcessesByName("cmd"); 


// find that one you interested in 
Process mypro; 

Suscribirse a Process.Exited caso de que al igual que

mypro.Exited += (s,e) => 
{ 
    //here upload the file 
} 

En caso de trabajo por usted.

+0

¡Creo que nunca deberías hacerlo así! porque, ¿qué pasa si hay más de un proceso único llamado "cmd". Si desea suscribirse al proceso, agregue algunos filtros al código, e.h. el nombre de la ventana de proceso y no el proceso en sí. –

+0

@ MarioFraiß: seguro. De hecho, la historia sobre cómo * ese * cmd proceso se saltó en mi publicación. Necesitas una especie de "clave segura" para poder encontrar el 'cmd.exe' que se solicitó. – Tigran

1

También voy gustaría sugerir que debe salvar lo que desea cargar los archivos no válidos tarde para que no haya roto/subidos. De esta forma, la próxima vez que se inicie la aplicación, se puede realizar la carga. Éste, al menos, trabaja para sistema de cierre de sesión/Paradas:

SystemEvents.SessionEnding += (SystemEvents_SessionEnding); 

private static void SystemEvents_SessionEnding(object sender, SessionEndingEventArgs e) 
{ 
    //code to run on when user is about to logoff or shutdown 
} 
Cuestiones relacionadas