c# - 如何检测父进程的关闭?

标签 c# .net vb.net winapi

我正在开发一个 .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/

相关文章:

c# - 您对一组编码标准或最佳实践有什么好的建议/链接可以遵循吗?

c# - 带有 Oracle 的 Entity Framework ,NUMBER(10) 个错误

c# - 使用 C# 和 Selenium 进行 Nunit 参数化

.net - 通过 WebClient.DownloadData 自动解压 gzip 响应

c# - 私有(private)构造函数的奇怪智能感知行为

mysql - 在mysql和vb.net上插入数据

.net - VB.NET:如何处理变量类型(参数和返回值)?

c# - 在 .cs page/rowdatabound 的 gridview 列中以 MM/DD/YY 格式显示日期?

c# - Unity 3D/球体中的翻转法线

vb.net - Visual Basic资源