力SetWinEventHook是从主线程调用 [英] Force SetWinEventHook to be called from main thread
问题描述
我想注册新创建的进程的一些对象级的WinEvents挂钩,但作为官方的文档说:
有关外OF-背景事件,该事件被调用SetWinEventHook在同一个线程上提供。
块引用>
我的问题是,我从不是主要原因之一,这将导致在没有收到任何回调以外的线程调用SetWinEventHook主线程。我一直在寻找一种方式来触发(从另一个线程)在主线程SetWinEventHook方法调用。明知这是一个控制台应用程序,调用而BeginInvoke解决方案没有奏效。我也试过事件和事件处理程序。
我希望我的问题不会被误解。下面的代码和输出。
//存储回调作为一个字段,以确保垃圾收集不动它
//而在托管代码被使用,这是比使用的GCHandle
静态WinEventDelegate procDelegate =新Native.WinEventDelegate(WinEventProc)更容易;
静态无效WinEventProc(IntPtr的hWinEventHook,UINT事件类型,IntPtr的HWND,
INT idObject,诠释idChild,UINT dwEventThread,UINT dwmsEventTime)
{
Console.WriteLine( 回调,TID =+ Thread.CurrentThread.ManagedThreadId);
}
ManagementEventWatcher processStartEvent =新ManagementEventWatcher(SELECT * FROM Win32_ProcessStartTrace);
无效processStartEvent_EventArrived(对象发件人,EventArrivedEventArgs E)
{
串processName = e.NewEvent.Properties [ProcessName] Value.ToString()。
INT进程ID = Convert.ToInt32(e.NewEvent.Properties [的ProcessID]值。);
工艺过程= Process.GetProcessById(进程ID);
IntPtr的钩= SetWinEventHook(事件ID,事件ID,IntPtr.Zero,procDelegate,(UINT)process.Id,
GetWindowThreadProcessId(process.MainWindowHandle,IntPtr.Zero),
Native.WINEVENT_OUTOFCONTEXT |母语.WINEVENT_SKIPOWNPROCESS | Native.WINEVENT_SKIPOWNTHREAD);
如果(钩== IntPtr.Zero)Console.WriteLine(挂钩失败);
Console.WriteLine(事件,TID =+ Thread.CurrentThread.ManagedThreadId);
}
无效watchProcess()
{
processStartEvent.EventArrived + =新EventArrivedEventHandler(processStartEvent_EventArrived);
processStartEvent.Start();
}
静态无效的主要(字串[] args)
{
Console.WriteLine(主,TID =+ Thread.CurrentThread.ManagedThreadId);
watchProcess();
MessageBox.Show(消息循环);
}
输出:
<块引用>
为主,TID = 1结果
事件,TID = 4 //重复多次,新工艺创造
块引用>
解决方案曾经有过同样的问题。从任何形式使用Invoke方法:
this.Invoke(新MethodInvoker(()=> StartEventListener()));
问候
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
解决方案Have had the same problem. Use Invoke method from any form:
this.Invoke(new MethodInvoker(() => StartEventListener()));
Regards
这篇关于力SetWinEventHook是从主线程调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!