我试图通过以下代码拦截event_object_create
和event_object_destroy
事件:
class NameChangeTracker
{
private const uint EVENT_OBJECT_CREATE = 0x00008000;
private const uint EVENT_OBJECT_DESTROY = 0x00008001;
private const uint WINEVENT_OUTOFCONTEXT = 0;
//DLL imports
private static WinEventDelegate procDelegate = new WinEventDelegate(NameChangeTracker.WinEventProc);
private delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
private static void WinEventProc(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
if(idObject==0 && idChild==0)
{
if(hwnd.ToInt32() == getspotify().ToInt32())
{
switch(eventType)
{
case EVENT_OBJECT_CREATE:
Console.WriteLine("inside create case");
break;
case EVENT_OBJECT_DESTROY:
Console.WriteLine("inside destroy case");
break;
}
}
}
}
内部main
方法
public static void Main()
{
NameChangeTracker tracker = new NameChangeTracker();
IntPtr hwnd = tracker.getspotify(); // returns hwnd using "FindWindow()" method.
int num = tracker.getprocessid(hwnd); //returns processid using "GetWindowThreadProcessId()" method.
IntPtr hWinEventHook = SetWinEventHook(0x00008000,0x00008001,IntPtr.Zero, procDelegate, 0, 0, 0);
Message msg = new Message();
while(GetMessage(ref msg,hwnd,0,0))
UnhookWinEvent(hWinEventHook);
}
}
当我手动关闭我的应用程序(Spotify)并打印inside create case
和inside destroy case
的组合时,我的上述代码会捕获事件,但当我restart
我的应用程序时,它在控制台中不打印任何内容
那么,我如何确保我的程序不断监听从create & destroy
发出的Application(Spotify)
事件,并且是上述方法的正确方法。
这是我的ConsoleOutput。
修改-1
所以,我改变了idProcess
参数来听取所有过程中的事件。但是我的程序现在只打印inside create case
,当我启动我的应用程序时,它会在我手动关闭它时不打印任何内容。
答案 0 :(得分:3)
这里可能发生的事情是,当您重新启动目标应用程序(Spotify)时,它会获得一个新的进程ID - 因此您的代码仍在侦听旧进程ID - 忽略它。
您无法更改正在收听事件的PID,因此您基本上有两种选择:
随时收听所有流程中的事件,或
侦听来自特定进程的事件,当它死亡时,侦听从所有进程创建事件,检查是否有任何Create事件是否为top-级别HWND来自您关心的过程 - 然后只听那个。 (请注意,因为这里存在潜在的竞争条件;在您获得告知您旧实例已消失的destroy事件之后,可能会在开始侦听来自所有进程的事件之前创建新实例,因此您应该进行扫描在您开始倾听安全的一面之后,所有顶级HWND都会发生。)
如果这只是一个供个人使用的实用程序,最简单的事情可能就是始终只是听取所有进程中的事件 - 但仍然只听取你关心的几种类型的事件,然后看看是否有任何性能的问题。如果没有,它运行正常而对系统性能没有任何明显影响,那就完成了!
(对于更专业的方法,您可能希望测量您忽略的剩余消息数量,并且可以获得更多数据以确定它是否可能是性能问题。当用户界面处于稳定状态时经常会发生这种情况,因此可能不是问题的全部 - 但是当打开应用程序时,你可以得到一大堆。)