如何监视我生成的进程中的活动?
Posted
技术标签:
【中文标题】如何监视我生成的进程中的活动?【英文标题】:How can I monitor activity in a process that I spawned? 【发布时间】:2012-09-12 15:08:54 【问题描述】:我的任务是尝试监视从初始程序生成的所有 GUI 程序中的活动,并在它们在一段时间内不活动时终止它们。这不可能是系统活动,因为即使用户只是使用另一个程序一段时间(不是由初始程序产生的),我们也必须关闭程序。应用程序生成过程是一个 .Net 程序,不会改变。我能够使用SetWindowsHookEx
从.Net 设置低级挂钩(WH_KEYBOARD_LL
和WH_MOUSE_LL
),但不确定如何将消息与我已启动的进程相关联(使用System.Diagnostics.Process
。)我可以来自执行挂钩的应用程序的挂钩事件,但当我尝试挂钩到特定线程以生成衍生程序时,它总是会失败。
我最接近的方法是创建一个代表 .Net 程序调用 SetWindowsHookEx
的 C++ dll。使用这种方法,我可以连接到生成的 notepad.exe 的第一个线程,但永远不会调用回调函数。如果我指定线程 id 为 0,则在原始应用程序中有活动时调用回调,因此我知道 SetWindowsHookEx
在这种情况下有效。
我还没有完全理解挂钩,但是从我所读到的内容来看,这将不起作用,因为 dll 回调函数地址对挂钩进程毫无意义。那是我遇到的问题吗?如果是这样,有没有办法解决这个问题,或者有人可以建议一种替代方法来确定是否正在积极使用生成的进程?
.Net (C#) 代码:
private const int WH_MOUSE = 14;
[DllImport("TestHook.dll", EntryPoint="InitializeHook", SetLastError=true, CharSet=CharSet.Unicode, ExactSpelling=true, CallingConvention=CallingConvention.StdCall)]
private static extern bool InitializeHook(uint hookType, int threadID);
private void HookEm()
//...
System.Diagnostics.Process testProcess = System.Diagnostics.Process.Start("notepad");
if(!InitializeHook(WH_MOUSE, testProcess.Threads[0].Id)) // The notepad.exe thread I know hooks
MessageBox.Show("Boom!");
//...
C++ DLL:
HHOOK hookValue;
bool InitializeHook(UINT hookID, int threadID)
//... Determining which callback to use
hookValue = SetWindowsHookEx(hookID, (HOOKPROC)MouseHookCallback, _dllInstance, threadID);
//...
return hookValue != NULL
static LRESULT CALLBACK MouseHookCallback(int code, WPARAM wparam, LPARAM lparam)
//From what I can see, this is never touched when hooking a thread on an outside process
所有这些目前都是在 32 位 Windows XP 计算机上完成的。我明白,需要一个单独的 64 位 dll 来处理生成的 64 位应用程序。
【问题讨论】:
您的实际InitializeHook
是否返回正确的SetWindowsHookEx
结果?
我忘了把它放在那里,但是 C++ dll 确实会跟踪来自SetWindowsHookEx
的返回值,只有当SetWindowsHookEx
返回一个非空值时,来自InitializeHook
的返回才为真价值
【参考方案1】:
对于遇到类似问题的任何人,我们的最终解决方案是使用 GetWindowThreadProcessId(GetForegroundWindow(), ref foregroundWindowProcessId)
每隔一段时间检查前台窗口,并保留我们生成的进程 ID 的地图。每次触发此计时器时,我们都会设置一个布尔值来检查调用 CallNextHookEx
的函数,因为它必须高效/快速,否则 Windows 将解开我们的钩子。然后我们使用上面的布尔值和来自SetWindowsHookEx
的系统挂钩来确定用户是否在我们的应用程序中处于活动状态。此解决方案不需要 C++ dll。
【讨论】:
以上是关于如何监视我生成的进程中的活动?的主要内容,如果未能解决你的问题,请参考以下文章