我正在开发一个 .NET 控制台应用程序,它需要在退出时清理资源。我遇到的问题是,如果通过控制台窗口 [X]、任务管理器/进程资源管理器或以编程方式使用 WM_CLOSE 关闭 cmd 父级,我不会收到任何通知。我可以忍受无法处理来自 Task Mgr 的Kill Process。或 ProcExp。父控制台的 WM_CLOSE 是此应用程序在完成处理之前最有可能关闭的方式。
以下是到目前为止我尝试注册的事件:
AppDomain.CurrentDomain.ProcessExit += CurrentDomainProcessExit;
AppDomain.CurrentDomain.UnhandledException += CurrentDomainUnhandledException;
Console.CancelKeyPress += ConsoleCancelKeyPress;
Application.ApplicationExit += ApplicationApplicationExit;
Process parentProcess = ProcessInfo.GetParentProcess(
Process.GetCurrentProcess());
parentProcess.Disposed += ParentDisposed;
parentProcess.Exited += ParentExited;
Process grandParentProcess = ProcessInfo.GetParentProcess(parentProcess);
grandParentProcess.Disposed += GrandParentDisposed;
grandParentProcess.Exited += GrandParentExited;
当我从控制台发送 CTRL+C 或应用程序不间断地完成时,这些事件会正确触发。但是当父应用程序(cmd 控制台)关闭时,它们都不会触发。 (父/祖 parent 进程不是 CLR,所以我不确定我是否会收到那些 Disposed/Exited 事件。那些只是在黑暗中拍摄。)我看过一些 pInvoke 的东西,但我宁愿不下去如果 .NET 是一个选项,那条路。
在这些情况下是否有检测和处理关机的方法?我对任何 .NET、pInvoke/Win32/C/C++ 解决方案持开放态度。 (基本上任何方式都可以在 Windows 平台上完成。)
谢谢。
附言我仍在使用 .NET 2.0,所以我不能使用 .NET 3.0+ 中引入的任何内容
最佳答案
您最好的选择可能是使用 P/Invoke。 Windows API 函数 SetConsoleCtrlHandler()
可能会如您所愿。
下面的示例代码是从 here 中窃取的(MSDN 上提供了类似的代码,here)。
class Program
{
[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
}
private static bool ConsoleCtrlCheck(CtrlTypes ctrlType)
{
// Put your own handler here
return true;
}
static void Main(string[] args)
{
SetConsoleCtrlHandler(new HandlerRoutine(ConsoleCtrlCheck), true);
}
}
关于c# - 如何检测父进程的关闭?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5736184/