【问题标题】:WinAPI CloseEvent throws NULL pointer exception [duplicate]WinAPI CloseEvent 引发 NULL 指针异常 [重复]
【发布时间】:2014-10-27 08:47:13
【问题描述】:

我开发了一个应用程序,它执行一些操作,例如在关闭应用程序事件时恢复网络适配器设置。该应用程序是在 win 7 64 位下用 c# 4.0 编写的,它使用 WinAPI 来捕获“控制台关闭事件”。
当我关闭它时,应用程序抛出 “'System.NullReferenceException' 类型的未处理异常。” 当我关闭它时,我认为这是由于在那个关闭控制台事件中我做一些操作。使用 setConsoleCtrlHandler 我们可以捕获“关闭控制台应用程序”事件,我们有大约 1-2 秒的时间窗口来执行我们的操作,但有时这 1-2 秒不足以完成我在此方法中必须做的所有事情.该方法只需不到 1 秒即可完成。这是我用来捕获关闭事件的代码以及触发事件时我正在执行的操作:

//WinAPI method that catches the close event
static class NativeMethods
{
    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
    }

    [DllImport("Kernel32")]
    public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add);

    public static bool ConsoleCtrlCheck(CtrlTypes ctrlType)
    {
        // Put your own handler here
        switch (ctrlType)
        {
            case CtrlTypes.CTRL_CLOSE_EVENT:
                Console.WriteLine("Program being closed!");
                try
                {
                    //do stuff
                }
                catch(Exception ex)
                {
                    Console.WriteLine("FAILED");
                }
                break;
        }
        return true;
    }
}

//In Program.cs I register to catch the window events:
NativeMethods.SetConsoleCtrlHandler(new NativeMethods.HandlerRoutine(NativeMethods.ConsoleCtrlCheck), true);

您对我应该如何避免该问题并在应用关闭之前执行所需方法有任何想法吗?
谢谢

【问题讨论】:

  • 请显示更多代码。请将电话转至SetConsoleCtrlHandler。我希望看到您持有对代表的引用以阻止它被收集。
  • 我添加了其他细节,谢谢
  • 应用程序可能因各种原因而终止,而没有机会进行清理。执行诸如更改网络适配器之类的事情并期望在退出时进行清理是非常值得怀疑的。 Windows 有Filtering Platform,它更有可能做任何你想做的事情。
  • 我正在考虑一个单独的应用程序,它将监视进程以及何时关闭特定进程以执行所有这些网络适配器设置,但首先我想确保我不能同时执行此操作应用程序。您能否更具体地了解过滤平台以及它如何帮助我解决这个问题(关闭应用程序时进行一些计算..),从我那里可以看到它指的是 TCP/IP 数据包过滤。谢谢

标签: c# .net winapi console


【解决方案1】:

您将委托传递给非托管代码,但未采取任何措施使该委托保持活动状态。就垃圾收集器所知,只要SetConsoleCtrlHandler 返回,就不再有对委托的引用。代表没有理由让它活着。

您应该在静态变量中保存对委托的引用,以防止它被收集。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    • 1970-01-01
    • 2014-02-04
    • 1970-01-01
    相关资源
    最近更新 更多