查找当前的Windows应用程序

时间:2009-02-03 00:10:11

标签: c# windows

我正在尝试编写我希望是一个简单的应用程序跟踪器。也就是说,每当新应用程序启动或正在运行的应用程序成为当前应用程序时,我都要记下该事件并开始计时它“在顶部”。

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

我认为我缺少的是要监控的Windows事件流等。

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

有任何提示,提示或作弊吗?

谢谢 - 乔纳森

5 个答案:

答案 0 :(得分:4)

我不确定是否有办法挂钩Windows事件,只是定期轮询System.Diagnostics.Process.GetProcesses()(例如,100ms)并查找新的/删除的进程(按进程ID进行比较) )应该做的工作。此外,Process.StartTime将为您提供流程开始的时间。

警告:与基于事件的方法(我都不知道)相比,此方法可能需要更高的处理量。不会观察到每次轮询之间开始和结束的进程,但是对于相当高的轮询频率来说这应该是非常罕见的(也许你甚至不关心这些进程)。说这个,这些都是轻微的缺陷,我建议你至少测试这个解决方案,因为它很简单。

答案 1 :(得分:4)

我认为最好的方法是使用windows“hooks”(即SetWindowsHookEx)。这些允许您挂钩到Windows核心功能,特别是有一个名为WH_CALLWNDPROC的,它在系统中的任何窗口接收消息时调用用户函数。

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

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

答案 2 :(得分:3)

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

+1 Noldorin让他回到0,这就是我能做的一切。 OP需要在非托管C / C ++中编写代码,创建DLL并使用管道或套接字等标准IPC机制来通知主机应用程序。或者民意调查,更容易。

答案 3 :(得分:2)

我曾经写过一个小应用程序来做这件事来跟踪我自己的工作习惯。我所做的是定期调用GetForegroundWindow()(每5秒钟或其他什么)并注意正在运行的应用程序。您可以从窗口句柄获取大量信息,而不仅仅是标题,而是一直到创建它的实际过程。

答案 4 :(得分:2)

这就是我使用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挂钩,如果有人提出解决方案,我会非常感兴趣。