I'm trying to register some object-level WinEvents hooks on new created processes but as the official documentation says :
For out-of-context events, the event is delivered on the same thread that called SetWinEventHook.
My problem is that I'm calling SetWinEventHook from a thread other than the main one which will result in not receiving any callback in the main thread. I have been looking for a way to trigger (from another thread) SetWinEventHook method call in the main thread. Knowing that it's a Console Application, Invoke and BeginInvoke solution did not work. I also tried Events and EventHandler.
I hope my problem won't be misunderstood. Here's the code and the output.
// storing the callback as a field to make sure the garbage collector do not move it
// while being used in managed code, this is easier than using GCHandle
static WinEventDelegate procDelegate = new Native.WinEventDelegate(WinEventProc);
static void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd,
int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
Console.WriteLine("callback, tid = " + Thread.CurrentThread.ManagedThreadId);
}
ManagementEventWatcher processStartEvent = new ManagementEventWatcher("SELECT * FROM Win32_ProcessStartTrace");
void processStartEvent_EventArrived(object sender, EventArrivedEventArgs e)
{
string processName = e.NewEvent.Properties["ProcessName"].Value.ToString();
int processID = Convert.ToInt32(e.NewEvent.Properties["ProcessID"].Value);
Process process = Process.GetProcessById(processID);
IntPtr hook = SetWinEventHook(eventId, eventId, IntPtr.Zero, procDelegate, (uint)process.Id,
GetWindowThreadProcessId(process.MainWindowHandle, IntPtr.Zero),
Native.WINEVENT_OUTOFCONTEXT | Native.WINEVENT_SKIPOWNPROCESS | Native.WINEVENT_SKIPOWNTHREAD);
if (hook == IntPtr.Zero) Console.WriteLine("Hooking failed");
Console.WriteLine("event, tid = " + Thread.CurrentThread.ManagedThreadId);
}
void watchProcess()
{
processStartEvent.EventArrived += new EventArrivedEventHandler(processStartEvent_EventArrived);
processStartEvent.Start();
}
static void Main(string[] args)
{
Console.WriteLine("main, tid = " + Thread.CurrentThread.ManagedThreadId);
watchProcess();
MessageBox.Show("Message loop");
}
Output :
main, tid = 1
event, tid = 4 // repeated as many times as new processes created