I am sitting infront of my pc wondering how to get all added events. I just read some articles including A C# Bedtime Story to better understand events and I think that I got the main idea now. But still I couldn't figure out how to get the List of methods/delegates that are executed if an event is fired. Actually in my case it'd be enough if I knew if any method/delegate is assigned to a certain event.
for example: I am using Gma.UserActivityMonitor
(for keyboard/mouse-hooking)
Now I want to know if the event HookManager.KeyUp
event is not null.
If it is null a delegate shout be added. In my case this one \/
HookManager.KeyUp += new KeyEventHandler(HookManager_KeyUp);
Edit
example code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using Gma.UserActivityMonitor;
namespace EventTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
HookManager.KeyUp += new KeyEventHandler(HookManager_KeyUp);
Delegate[] a = GetEventSubscribers(button1, "Click");
label1.Text = a[0].Method.ToString();
}
void HookManager_KeyUp(object sender, KeyEventArgs e)
{
/* Do something*/
}
bool NoEventAttached()
{
return false;
}
public static Delegate[] GetEventSubscribers(object target, string eventName)
{
Type t = target.GetType();
var eventInfo = t.GetEvent(eventName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
do
{
FieldInfo[] fia = t.GetFields(
BindingFlags.Static |
BindingFlags.Instance |
BindingFlags.NonPublic);
foreach (FieldInfo fi in fia)
{
if (fi.Name == eventName)
{
Delegate d = fi.GetValue(target) as Delegate;
if (d != null)
return d.GetInvocationList();
}
else if (fi.FieldType == typeof(EventHandlerList))
{
----> var obj = fi.GetValue(target) as EventHandlerList;
var eventHandlerFieldInfo = obj.GetType().GetField("head", BindingFlags.Instance | BindingFlags.NonPublic);
do
{
var listEntry = eventHandlerFieldInfo.GetValue(obj);
var handler = listEntry.GetType().GetField("handler", BindingFlags.Instance | BindingFlags.NonPublic);
if (handler != null)
{
var subD = handler.GetValue(listEntry) as Delegate;
if (subD.GetType() != eventInfo.EventHandlerType)
{
eventHandlerFieldInfo = listEntry.GetType().GetField("next", BindingFlags.Instance | BindingFlags.NonPublic);
obj = listEntry as EventHandlerList; <-----------
continue;
}
if (subD != null)
{
return subD.GetInvocationList();
}
}
}
while (eventHandlerFieldInfo != null);
}
}
t = t.BaseType;
} while (t != null);
return new Delegate[] { };
}
private void button1_Click(object sender, EventArgs e)
{
}
private void button1_MouseClick(object sender, MouseEventArgs e)
{
}
}
}
Take note to this console application, and specifically the line calling
GetInvocationList()
. That method returns the list of delegates attached. EachDelegate
has aMethod
property. EachMethod
property has aName
.Delegate is Owned by You
Delegate is NOT Owned by You
Ok, this gets a little messy, but it gets you the answer you want. Even if the internal implementation uses an
EventHandlerList
(which is somewhat common), but I cannot gaurantee it would work in absolutely every scenario because there can be so many different internal representations.However, hopefully this will work for you. As you can see in the example I'm using the
BackgroundWorker
class as my example class for getting the invocation list for a specific event I do not own.Finally, though I made some pretty big modifications to the code, I have to give credit to Bob Powell for getting me started on this.
I believe that simply comparing HookManager.KeyUp to null will give you your answer.
Other than that, though, unless things have changed since last I looked into it (quite possible) it's rather difficult to get an actual list of the delegates associated with an event. But if the value is null, that tells you that no delegates are associated with it.