C# – Why is EventInfo.RemoveEventHandler throwing a NullReferenceException

.netc++mshtmlreflection

I've got some code that is using reflection to install .NET event handlers on MSHTML objects in an Internet Explorer BHO, and it appears to be working fine. I'm running into trouble, however, when I try to remove the event handlers.

This is what the code for event handler installation and removal looks like:

public class HandlerExample {
    private static void Handler(IHTMLEventObj e) { ... }
    private static Delegate handlerDelegate;

    public static void InstallHandler(IHTMLElement target, string eventName)
    {
        // FindInterface() finds the correct event interface for the particular subclass of
        // IHTMLElement that target really is
        Type eventInterface = FindInterface(target);
        EventInfo eInfo = eventInterface.GetEvent(eventName);
        Type tHandler = eInfo.EventHandlerType;

        handlerDelegate = Delegate.CreateDelegate(tHandler, typeof(HandlerExample), "Handler");

        eInfo.AddEventHandler(target, handlerDelegate);
    }

    public static void RemoveHandler(IHTMLElement target, string eventName)
    {
        Type eventInterface = FindInterface(target);
        EventInfo eInfo = eventInterface.GetEvent(eventName);
        eInfo.RemoveEventHandler(target, handlerDelegate); // THIS LINE CRASHES
    }
}

The call to InstallEventHandler works fine, and Handler then gets called when the event is triggered in the browser. When I call RemoveEventHandler with the same arguments as the InstallEventHandler call, the last line throws a TargetInvocationException, with an inner exception of NullReferenceException. I can't figure out what I'm doing wrong here, and the stack trace is not much help.

EDIT: I've stepped through the code in the debugger, and none of the object variables I directly reference are null.

I've also tried calling both AddEventHandler and RemoveEventHandler in the InstallHandler method, and that works correctly.

Stack trace follows:

System.Reflection.TargetInvocationException occurred
  Message="Exception has been thrown by the target of an invocation."
  Source="mscorlib"
  StackTrace:
       at System.RuntimeMethodHandle._InvokeMethodFast(Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
       at System.RuntimeMethodHandle.InvokeMethodFast(Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeTypeHandle typeOwner)
       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
       at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
       at System.Reflection.EventInfo.RemoveEventHandler(Object target, Delegate handler)
       at RemoveHandler(IHTMLElement target, String eventName)
  InnerException: System.NullReferenceException
       Message="Object reference not set to an instance of an object."
       Source="Microsoft.mshtml"
       StackTrace:
            at mshtml.HTMLTextContainerEvents2_EventProvider.remove_onclick(HTMLTextContainerEvents2_onclickEventHandler )
            at mshtml.HTMLTextAreaElementClass.HTMLTextContainerEvents2_Event_remove_onclick(HTMLTextContainerEvents2_onclickEventHandler )
       InnerException: 

What could be causing this, and how can I fix it?

Best Solution

Well it looks like your handlerDelegate is null when you are calling the RemoveHandler. I am not sure why this would happen, but have you tried instantiating the handlerDelegate right before calling RemoveEventHandler?

Related Question