У меня есть код, который использует отражение для установки обработчиков событий .NET на объекты MSHTML в Internet Explorer BHO, и, похоже, он работает нормально. Однако у меня возникают проблемы, когда я пытаюсь удалить обработчики событий.
Вот так выглядит код для установки и удаления обработчика событий:
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
}
}
Вызов InstallEventHandler
работает нормально, а затем Handler
вызывается, когда событие запускается в браузере. Когда я вызываю RemoveEventHandler
с теми же аргументами, что и вызов InstallEventHandler
, последняя строка выдает TargetInvocationException
с внутренним исключением NullReferenceException
. Я не могу понять, что я здесь делаю не так, да и трассировка стека не особо помогает.
РЕДАКТИРОВАТЬ: Я прошел через код в отладчике, и ни одна из переменных объекта, на которые я ссылаюсь напрямую, не имеет значения NULL.
Я также пробовал вызывать как AddEventHandler
, так и RemoveEventHandler
в методе InstallHandler, и это работает правильно.
След стека:
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:
Что могло быть причиной этого и как это исправить?