Call has been made on garbage collected delegate in C#?

The problem is that:

hhook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, hInstance, 0);

is just syntactic sugar for:

hhook = SetWindowsHookEx(WH_KEYBOARD_LL, new keyboardHookProc(hookProc), hInstance, 0);

and so the keyboardHookProc object is just local and will get disposed of since SetWindowsHookEx doesn’t do anything to actually hold onto it in the managed world.

To fix this, up at the top where you define your member variables, add one more like this:

IntPtr hhook = IntPtr.Zero
private keyboardHookProc hookProcDelegate;

then change your constructor to be:

public globalKeyboardHook()
{
    hookProcDelegate = hookProc;
    hook();
}

and then change your hook() method to be:

public void hook()
{
    IntPtr hInstance = LoadLibrary("User32");
    hhook = SetWindowsHookEx(WH_KEYBOARD_LL, hookProcDelegate, hInstance, 0);
}

That way you’re using a delegate that is stored as a member variable and will be alive as long as your globalKeyboardHook object is alive.

Leave a Comment