Run code on console close?

Ryan S. picture Ryan S. · Mar 27, 2012 · Viewed 8.4k times · Source

I am writing a C# app that needs to upload a file when the console is closed (be it via the X button, or the computer is shut down).

How could I do this?

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

Only runs when I issue the exit command to the console, not when I hit the red close button.

Please only answer if the solution runs both when the console is closed via the X button, and when the computer is shut down (normally via Windows, I know you can't if the power is pulled xD).

Answer

Mario Fraiß picture Mario Fraiß · Mar 27, 2012

You have to invoke the WIN32 API, to do this, just have a look at this post here http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/707e9ae1-a53f-4918-8ac4-62a1eddb3c4a/

I copied the relevant code for you from there:

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
}

It does exactly what you need.

Greetings,