C# 如何在命令行应用程序中接收系统关闭或退出事件

A.G*_*ndt 4 c# command-line exit

我正在尝试,但到目前为止我发现的一切似乎都以 GUI 和表单应用程序为中心。那不是我正在使用的。

最终它将成为一项服务,但在完成之前我将它作为普通应用程序运行,问题是如果我不小心关闭它,它会使另一个服务挂起长达 30 分钟的错误数据. 我虽然添加一个监听器来捕捉应用程序被关闭会很容易。

但我就是想不通。

Jot*_*aBe 5

在这里,您有一个完美的解决方案,可以满足您的需求:

在 C# 中检测控制台应用程序退出

该代码检测将关闭应用程序的所有可能事件:

  • 控制+C
  • 控制+中断
  • 关闭事件(“正常”关闭程序,使用关闭按钮)
  • 注销事件(使用注销)
  • 关机事件(系统关闭)
namespace Detect_Console_Application_Exit2
{
  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_C_EVENT:
          isclosing = true;
          Console.WriteLine("CTRL+C received!");
          break;

        case CtrlTypes.CTRL_BREAK_EVENT:
          isclosing = true;
          Console.WriteLine("CTRL+BREAK received!");
          break;

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

        case CtrlTypes.CTRL_LOGOFF_EVENT:
        case CtrlTypes.CTRL_SHUTDOWN_EVENT:
          isclosing = true;
          Console.WriteLine("User is logging off!");
          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

    }
}
Run Code Online (Sandbox Code Playgroud)

  • @A.Grandt 当您移动到 ​​Windows 服务时,您可以处理停止事件。如果你想成功,你应该启动一个工作线程并从停止事件处理程序控制它。即,当停止请求到达时,事件处理程序应该通知工作线程它应该停止,并等待它停止,然后再关闭服务。当停止事件处理程序中的代码完成执行时服务关闭,您需要使用某种同步机制来通知工作线程它应该停止,并等待它停止。 (2认同)