title: The definitive code that prevents a c# console app from exiting [until custom cleanup code has completed]
body: <p>Can we work together to come up with something that works for control-c, control-break, log off, window X button pressed, etc?</p>
  
  <p>Here is what I have so far:</p>
  
  <pre><code>class Program
  {  
      private static ConsoleEventHandlerDelegate consoleHandler;
      delegate bool ConsoleEventHandlerDelegate(CtrlTypes eventCode);
  
      static void Main(string[] args)
      {
          consoleHandler = new ConsoleEventHandlerDelegate(ConsoleCtrlCheck);
          SetConsoleCtrlHandler(consoleHandler, true);
  
          System.Diagnostics.Process.GetCurrentProcess().Exited 
             += delegate(object sender, EventArgs e) 
          {              
              GeneralManager.Stop();
          };
  
          Console.CancelKeyPress += delegate(object sender,
                                  ConsoleCancelEventArgs e)
          {
              e.Cancel = false;
              GeneralManager.Stop();
          };
  
          GeneralManager.Start();
      }
  
      private static bool ConsoleCtrlCheck(CtrlTypes ctrlType)
      {
          switch (ctrlType)
          {                
              case CtrlTypes.CTRL_C_EVENT:
  
                  Console.WriteLine("CTRL+C received!");
                  GeneralManager.Stop();
                  break;
  
              case CtrlTypes.CTRL_BREAK_EVENT:
                  isclosing = true;
                  Console.WriteLine("CTRL+BREAK received!");
                  GeneralManager.Stop();
                  break;
  
              case CtrlTypes.CTRL_CLOSE_EVENT:
  
                  Console.WriteLine("Program being closed!");
                  GeneralManager.Stop();
                  break;
  
              case CtrlTypes.CTRL_LOGOFF_EVENT:
              case CtrlTypes.CTRL_SHUTDOWN_EVENT:
  
                  Console.WriteLine("User is logging off!");
                  GeneralManager.Stop();
                  break;                           
          }
          return true;
      }
  
      #region unmanaged
  
              [DllImport("kernel32.dll")]
            static extern bool SetConsoleCtrlHandler(ConsoleEventHandlerDelegate
              handlerProc, bool add);
  
      public delegate bool HandlerRoutine(CtrlTypes CtrlType);
  
      public enum CtrlTypes
      {
          CTRL_C_EVENT = 0,
          CTRL_BREAK_EVENT,
          CTRL_CLOSE_EVENT,
          CTRL_LOGOFF_EVENT = 5,
          CTRL_SHUTDOWN_EVENT
      }
  
      #endregion
  }
  </code></pre>
  
  <p>Two problems:</p>
  
  <ol>
  <li><p>In the Managed Control-Break handler, if we set <code>e.Cancel = true</code> it fails with an exception for .Net4. This is noted in the MSDN article with no work-around: <a href="http://msdn.microsoft.com/en-us/library/system.consolecanceleventargs.cancel.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/system.consolecanceleventargs.cancel.aspx</a></p></li>
  <li><p>I don't know how to cancel the close in the <code>ConsoleCtrlCheck</code>. I get a second or two to do some cleanup, but I'd rather cancel and make sure it all gets done properly.</p></li>
  </ol>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>Thanks for the replies. Upvoted both. Will wait to see if anyone can come up with a reply that directly solves what I asked for, otherwise will accept one of the "use NT services" answers.</p>