处理应用程序的EVENT_OBJECT_CREATE& EVENT_OBJECT_DESTROY事件

时间:2012-03-19 00:50:29

标签: c# windows winapi

我试图通过以下代码拦截event_object_createevent_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 caseinside destroy case的组合时,我的上述代码会捕获事件,但当我restart我的应用程序时,它在控制台中不打印任何内容

那么,我如何确保我的程序不断监听从create & destroy发出的Application(Spotify)事件,并且是上述方法的正确方法。

这是我的ConsoleOutput

修改-1

所以,我改变了idProcess参数来听取所有过程中的事件。但是我的程序现在只打印inside create case,当我启动我的应用程序时,它会在我手动关闭它时不打印任何内容。

1 个答案:

答案 0 :(得分:3)

这里可能发生的事情是,当您重新启动目标应用程序(Spotify)时,它会获得一个新的进程ID - 因此您的代码仍在侦听旧进程ID - 忽略它。

您无法更改正在收听事件的PID,因此您基本上有两种选择:

  • 随时收听所有流程中的事件,或

  • 侦听来自特定进程的事件,当它死亡时,侦听从所有进程创建事件,检查是否有任何Create事件是否为top-级别HWND来自您关心的过程 - 然后只听那个。 (请注意,因为这里存在潜在的竞争条件;在您获得告知您旧实例已消失的destroy事件之后,可能会在开始侦听来自所有进程的事件之前创建新实例,因此您应该进行扫描在您开始倾听安全的一面之后,所有顶级HWND都会发生。)

如果这只是一个供个人使用的实用程序,最简单的事情可能就是始终只是听取所有进程中的事件 - 但仍然只听取你关心的几种类型的事件,然后看看是否有任何性能的问题。如果没有,它运行正常而对系统性能没有任何明显影响,那就完成了!

(对于更专业的方法,您可能希望测量您忽略的剩余消息数量,并且可以获得更多数据以确定它是否可能是性能问题。当用户界面处于稳定状态时经常会发生这种情况,因此可能不是问题的全部 - 但是当打开应用程序时,你可以得到一大堆。)