我有一个简单的库,可以覆盖控制台的关闭事件,以便在关闭之前完成各种任务。只要用户或外部程序关闭控制台(ctrl + C,关闭窗口等),这就有效,但是,当控制台应用程序使用Environment.Exit()时,它会关闭而不会被识别为关闭事件之一。
以下是关闭处理程序的代码:
namespace ShutdownLibrary
{
public class ConsoleHandler
{
public bool ExitSystem = false; // Optional assistance for implementation.
[DllImport("Kernel32")]
private static extern bool SetConsoleCtrlHandler(EventHandler handler, bool add);
private delegate bool EventHandler(CtrlType sig);
private EventHandler _handler;
/// <summary>
/// Windows events to listen for.
/// </summary>
public enum CtrlType
{
CTRL_C_EVENT = 0,
CTRL_BREAK_EVENT = 1,
CTRL_CLOSE_EVENT = 2,
CTRL_LOGOFF_EVENT = 5,
CTRL_SHUTDOWN_EVENT = 6,
}
private bool Handler(CtrlType sig)
{
//Old .NET threading
var result = Task.Factory.StartNew<bool>(ShutdownTasks);
result.Wait();
return result.Result;
}
/// <summary>
/// Starts an EventHandler for console windows & calls overridable ShutdownTasks() when console is closed by any means.
/// </summary>
public void StartShutdownEventHandler()
{
_handler += new EventHandler(Handler);
SetConsoleCtrlHandler(_handler, true);
}
/// <summary>
/// Overridable method for tasks to action before the program is disposed.
/// </summary>
/// <returns>True when complete. False when not implemented.</returns>
public virtual bool ShutdownTasks()
{
ExitSystem = false;
return false;
}
}
}
应用程序本身使用关闭处理程序(ConsoleHandler),如下所示:
class ManagementServer : ServerManager
{
internal class ShutdownManager : ConsoleHandler
{
public override bool ShutdownTasks()
{
base.ShutdownTasks();
for (var i = 5; i >= 0; i--)
{
Thread.Sleep(1000);
Log.WriteToLog(string.Format("Management Server Shutting down in {0}", i));
}
Console.WriteLine("Good bye!");
return true;
}
}
//Override from ServerManager
public override void ShutDownManagementServer()
{
base.ShutDownManagementServer();
Environment.Exit(0);
}
static void Main(string[] args)
{
var sm = new ShutdownManager();
sm.StartShutdownEventHandler();
var manager = new ManagementServer();
manager.StartServer();
}
}
我认为ConsoleHandler类中的CtrlType枚举是罪魁祸首,但我似乎无法弄清楚缺少哪些值。
有什么想法吗?
答案 0 :(得分:-1)
退出不会执行正常关机。退出类似于拉动PC的电源线,而start-&gt; shutdown是正常的,并通知运行的应用程序系统正在关闭。
发出“退出”命令时,不会向正在运行的应用程序发送任何消息。您需要改为使用application.Shutdown。
请参阅what's difference between Environment.Exit() and Application.Shutdown()?
编辑:抱歉没有注意到它是一个控制台应用程序。您可以尝试处理AppDomain.ProcessExit事件。但说实话,我不认为这个事件有效。众所周知,如果发出粗鲁的退出命令(如结束任务),则不会触发此事件。退出是非常粗鲁的。