使用Win32监视打开的程序

时间:2011-09-23 15:04:28

标签: c++ windows winapi monitoring

我搜索了网络和各种论坛,但我找不到一件事,如果持续监控打开的程序,然后关闭另一个程序(不是被监控的程序),如果正在监视的程序发生了什么。

例如,假设已经打开了一个记事本窗口,然后用户或其他程序打开一个Windows资源管理器窗口。我想知道如何关闭记事本窗口而不与Windows资源管理器窗口交互(除了意识到它确实打开),以及如果用户关闭Windows资源管理器窗口,关闭记事本窗口。

提前致谢! :d

4 个答案:

答案 0 :(得分:8)

在Windows上,您可以使用PSAPI(Process Status API)来了解进程何时启动和终止。 EnumProcesses功能可以为您提供此信息。

确定进程终止的更可靠方法(因为进程ID可以重用)是等待其进程句柄(您将需要SYNCHRONIZE访问权限),您可以使用{{3}获取和进程'id从EnumProcesses获得。

要终止流程,始终会OpenProcess。要调用TerminateProcess,您需要具有PROCESS_TERMINATE访问权限的流程句柄。所有这些都假定您具有在要终止的进程上执行这些操作所需的权限。

答案 1 :(得分:5)

需要注意的一点是,流程和程序 - 或者至少是用户视为程序的东西 - 不一定是同一件事。

如果您使用PSAPI获取所有正在运行的进程的列表,您将看到很多后台进程根本不对应于打开的窗口。还有一种情况是单个进程可以打开多个顶级窗口。因此,当您有像记事本这样的简单案例时,一旦notepad.exe进程对应一个记事本窗口,您也会遇到以下情况:

  • Word,其中一个单词进程处理当前打开的所有单词文档(一个进程,多个窗口)
  • 资源管理器,其中一个exploere.exe进程处理所有打开的资源管理器窗口,以及控制面板窗口和任务栏等。
  • Chrome(和其他浏览器),其中每个标签都有自己的进程(许多进程,一个窗口!)

使用TerminateProcess可能不是关闭应用程序的最佳方式:它不等同于单击关闭按钮。它强行终止那里的整个过程,然后没有任何机会进行清理。如果你在Word上执行此操作,当它重新启动时,它将进入“恢复模式”,并表现为它最后一次没有干净地关闭。如果进程停止响应,最好留作最后的手段。此外,如果您在Word或资源管理器等进程上使用TerminateProcess,您最终将关闭该进程拥有的所有窗口,而不仅仅是一个特定的窗口。

鉴于所有这一切,如果你想基本上编写某种程序管理器,你可能最好采用以窗口为中心的方法而不是以流程为中心的方法。而不是监视正在运行的进程,监视顶级应用程序窗口。

有几种方法可以监听对窗口的更改;使用EVENT_CREATE / DESTROY的SetWinEventHook是监听正在创建或销毁的HWND的一种方法(你需要在这里进行过滤,因为它会告诉你所有的HWND - 以及更多! - 但你只关心顶级的,以及只有应用程序那个)。 SetWindowsHookEx可能有其他选项可以在这里工作(WH_CBT)。您还可以使用EnumWindows列出当前存在的窗口(同样,您需要过滤掉拥有的对话框和工具提示,当前不可见的HWND等)。

给定HWND,如果需要,可以使用GetWindowThreadProcessId获取进程信息。

要关闭窗口,首先尝试发送WM_SYSCOMMAND / SC_CLOSE是最好的事情:这更接近于单击关闭按钮,它为应用程序提供了清理的机会。请注意,某些应用会显示“您确定要关闭吗?”对话框,如果你最近没有保存 - 再次,它与用鼠标单击关闭按钮一致。

答案 2 :(得分:2)

在Windows上最常见的方法是使用Process Status API。您可以将此API用于enumerate processes但是,此API很烦人,因为它无法保证您获得完整的列表或流程。

枚举流程的更好方法是使用Tool Help Library,其中包括在任何给定时间采用完整snapshot of all processes in the system的方法。

答案 3 :(得分:1)

您需要Microsoft PSAPI(进程API),例如查看可以使用openProcess功能的开放进程。