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?