1

I developed an application that does some operations like restoring network adapter settings on closing the application event. The app is written in c# 4.0 under win 7 64 bit and it's using WinAPI to catch the "console closing event".
The app is throwing "An unhandled exception of type 'System.NullReferenceException' occurred in Unknown Module." when I close it, and, in my opinion is due to the fact that, in that closing console event I do some operations. Using setConsoleCtrlHandler we can catch the "closing console app " event and we have a time window of about 1-2 seconds to do our operations, but sometimes this 1-2 seconds aren't enough to complete all I have to do in this method. The method is taking less then 1 sec to finish. This is the code I'm using to catch the closing event and the operations I'm doing when the event is triggered:

//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);

Do you have any idea on how should I avoid the problem and execute the wanted methods before the app is closing?
Thx

Lucian
  • 874
  • 11
  • 33
  • Please show more code. Please show the call to `SetConsoleCtrlHandler`. I'm hoping to see that you hold a reference to the delegate to stop it from being collected. – David Heffernan Oct 27 '14 at 08:50
  • I added the other details, thx – Lucian Oct 27 '14 at 08:55
  • Apps can terminate for a miriad reasons w/o ever having a chance to cleanup. Doing things like network adapter changes and expect the clean up on exit is highly questionable. Windows has the [Filtering Platform](http://msdn.microsoft.com/en-us/library/windows/hardware/dn653358(v=vs.85).aspx) that is much more likely to do whtever you want to do. – Remus Rusanu Oct 27 '14 at 09:06
  • I was thinking of a separate app that will monitor the processes and when the specific process is closed to do all those network adapter settings, but first I wanted to be sure that I cannot do it in the same app. Can you be more specific on the Filtering platform and how it can help me solve this issue(when closing an app do some computations..), from what i can see there it refers to TCP/IP packet filtering. Thx – Lucian Oct 27 '14 at 09:14

1 Answers1

1

You pass a delegate to the unmanaged code but take no steps to keep that delegate alive. So far as the garbage collector knows, as soon as SetConsoleCtrlHandler returns, there are no more references to the delegate. There's no reason for the delegate to let it live.

You should hold a reference to the delegate in a static variable in order to prevent it being collected.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490