15

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

rshea0
  • 11,769
  • 9
  • 27
  • 40
  • 3
    sorry do say but there are scenarios where your process is killed so you cannot get this to work in every possible case (maybe you've seen it on Win7 where you hit shutdown and the system tells you that some processes prevent shutdown and you can choose to terminate them) – Random Dev Mar 27 '12 at 20:34
  • @CarstenKönig I understand there are situations like that, but I want it to at least work under a normal shutdown process in the event that the user doesn't force close the apps. – rshea0 Mar 27 '12 at 20:37
  • possible duplicate http://stackoverflow.com/questions/474679/capture-console-exit-c-sharp – Sergey Berezovskiy Mar 27 '12 at 20:39
  • @lazyberezovsky The person who answered that question said it doesn't work on Win7. – rshea0 Mar 27 '12 at 21:02
  • @ ryansworld10 that's why you selected copy of that answer as correct answer? – Sergey Berezovskiy Mar 27 '12 at 21:21

3 Answers3

14

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,

Mario Fraiß
  • 1,095
  • 7
  • 15
1

I'll also like to suggest you should save what you want to upload for later so you don't have broken/invalid files uploaded. That way next time the application is started, the upload can be performed. This one at least works for System Logoff/Shutdowns:

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
}
rtuner
  • 2,362
  • 3
  • 25
  • 37
0

May be something like this (assuming that I right understood you request)

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


// find that one you interested in 
Process mypro;

Subscribe to Process.Exited event of it like

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

Should work for you.

Tigran
  • 61,654
  • 8
  • 86
  • 123
  • I think, you never should do it like that! because what if there are more than one single processes called "cmd". If you wanna subscribe to the process, please add some filtering to the code, e.h. the name of the Process-Window and not the Process itself. – Mario Fraiß Mar 27 '12 at 20:43
  • @MarioFraiß: sure. Infact the story about how *that* cmd process located was skipped in my post. You need kind of "strong key" in order to be able to find the `cmd.exe` was requested. – Tigran Mar 27 '12 at 20:51