find当前的Windows应用程序

我试图写我希望是一个简单的应用程序跟踪器。 也就是说,无论何时一个新的应用程序启动,或者一个正在运行的应用程序变为最新的,我都要记下这个事件,并开始计时。

我有代码列出所有正在运行的当前应用程序,以及一些告诉我顶部窗口(总是我的testing控制台应用程序,自然)的代码。

我想我缺less的是要监视的Windows事件stream。

我使用.NET(C#首选)。

任何提示,提示或作弊?

谢谢 – 乔纳森

我认为最好的办法是使用windows“钩子”(即SetWindowsHookEx )。 这些允许你挂钩到windows核心功能,特别是有一个叫做WH_CALLWNDPROC ,当系统中的任何一个窗口收到一条消息时,都会调用一个用户函数。

您可以使用它来全局地侦听将窗口置于前台的消息和/或用于用户交互(鼠标,键盘)的消息。

但是,这是一个原始的Windows API函数,主要用于C / C ++的Windows DLL。 你可以在C#中实现它,但这是一堆你可能不想打开的蠕虫。 但是打开它可能是做你所问的最好的方法。

我不确定是否有方法来挂钩Windows事件,而是定期轮询System.Diagnostics.Process.GetProcesses()(例如,100ms)并寻找新的/删除的进程(按进程ID进行比较)工作。 另外,Process.StartTime会为您提供进程开始的时间。

警告:这种方法可能需要比较基于事件的方法更高的处理量(我没有意识到这一点)。 在每个轮询之间开始和结束的进程将不会被观察到,但是对于相当高的轮询频率来说,这确实是非常罕见的(也许你甚至不关心这些进程)。 说这些,这些都是轻微的损失,我建议你至少测试这个解决方案,因为它很简单。

这个问题越来越成为一个问题,低估的答案是正确的。 SetWindowsHookEx()确实需要能够捕获激活窗口获取的WM_ACTIVATE消息。 但是这需要WH_CALLWNDPROC或WH_SHELL钩子,这些钩子不能在C#中实现。 捕获这些需要在每个进程中注入一个DLL,托管程序集不能被注入到另一个进程。 CLR不能被初始化。

Noldorin +1让他回到0,这是我所能做的。 OP需要将他的代码写入非托管C / C ++,创建一个DLL并使用标准的IPC机制(如管道或套接字)来通知主机应用程序。 或者调查,更容易。

我曾经写过一个小应用程序来记录我自己的工作习惯。 我所做的就是定期(每5秒钟GetForegroundWindow()调用GetForegroundWindow() )并记下正在运行的应用程序。 您可以从窗口句柄中获取大量信息,而不仅仅是标题,直到创建它的实际过程。

这就是我使用Java的JNA所做的:

 final HWND child = User32Ext.INSTANCE.GetForegroundWindow(); final int length = User32.INSTANCE.GetWindowTextLength(child) * 2; final byte[] buffer = new byte[length]; User32.INSTANCE.GetWindowText(child, buffer, length); title = new String(buffer, Charset.forName("UTF-16LE")); 

其中User32Ext是我做的一个扩展,因为User32(在JNA的发行版中)没有以下接口:

 LRESULT callback(int nCode, WPARAM wParam, LPARAM lParam); 

我定期轮询活动窗口,因为我无法使用http://msdn.microsoft.com/en-us/library/ms997537.aspx中提到的HCBT_SETFOCUS钩子,如果有人拿出解决方案。