【问题标题】:Detecting whether a process is idle检测进程是否空闲
【发布时间】:2011-10-19 00:26:24
【问题描述】:

有没有办法检测 Windows 进程是否空闲?

idle 表示,当特定应用程序的进程没有处理任何事情时(应用程序正在等待用户输入)。

干杯

【问题讨论】:

  • 用户输入是什么意思?它是阻塞在 getc() 上的命令行应用程序,还是您的意思是 GUI 应用程序什么都不做,只是等到按下按钮?
  • 嘿巴特,正是“Gui 应用程序什么都不做,只是等到按下按钮”
  • 这需要明确了解受监控的应用程序。它显示按钮的事实并不等同于“空闲”(例如,取消按钮)。也许只是按照@cprogrammer 的建议使用 SetWindowHook 并监视您想了解的按钮和控件。

标签: c window jna


【解决方案1】:

你可以用 WH_FOREGROUNDIDLE 挂上一个钩子SetWindowsHookEx

【讨论】:

  • 嘿 cProgramming 感谢您的快速回放,我目前有一个 HWND,如何将 HWND 连接到 windowHookex?
  • 您应该告诉我们更多关于您的申请的信息。 SetWindowsHookEx 可以放在一个线程上,但如果你有一个 HWND,还有其他方法可以处理这个问题。就像 SetWindowLong 和 GWL_WNDPROC 一样,看看你什么时候没有收到消息,或者你是否正在使用 MFC 有一条名为 WM_KICKIDLE 的消息,它是 MFC 在对话框空闲时发送的消息。
  • 我会尝试重新措辞。以应用程序的安装为例: - 用户运行 setup.exe,然后输入一些设置(配置程序),之后会有某个点开始安装程序。当程序完成后,它的进程应该是空闲仪式吗?等待用户输入,这就是我想要弄清楚的。
  • 你在这个过程中吗?是控制台还是 gui 应用程序?
  • Gui App,我打算使用 GetForegroundWindow 来获取句柄并获取它的进程 ID,然后以某种方式检测它何时空闲
【解决方案2】:

如果您的意思是要检测应用程序是否满意并接收消息(用户输入),请检查此函数的返回:

SendMessageTimeout(HwndInQuestion, WM_NULL, 0, 0, SMTO_ABORTIFHUNG, 10);

只需将超时时间(示例中为 10 毫秒)设置为您认为适合您使用的时间即可。

【讨论】:

  • 嗨 noelicus,我想检测特定应用程序何时请求用户输入。
【解决方案3】:

我在 MFC 案例中发现的关于此主题的简短摘要,您希望在进程空闲时收到通知(做一些后台工作等),但不是以轮询/等待方式

(变量名是建议):

-> 如果它是一个没有模式对话框的 MFC 应用程序:

add ON_MESSAGE_VOID(WM_IDLEUPDATECMDUI,OnIdleUpdateCmdUI) to message map together
with the method afx_msg void OnIdleUpdateCmdUI()

-> 如果它是 MFC 应用程序中的对话框:

add ON_MESSAGE(WM_KICKIDLE, OnKickIdle) to message map together 
with the method afx_msg LRESULT OnKickIdle(WPARAM wParam, LPARAM lParam);

-> 如果你想要两者(应用程序和对话框):

.) 向主框架添加一个公共成员变量(也可以是静态全局变量)

HOOKPROC m_detectIdleHook

.) 将方法原型添加到主框架的头文件中

friend LRESULT CALLBACK OnForeGroundIdle( int nCode, WPARAM wParam, LPARAM lParam )

有这个内容(注意不是主框架的成员函数!)

LRESULT CALLBACK OnForeGroundIdle( int nCode, WPARAM wParam, LPARAM lParam )
{   
    // Do/check stuff in idle time here
    return ::CallNextHookEx( (HHOOK)((CMyMainFrame*)AfxGetMainWnd())->m_detectIdleHook, nCode, wParam, lParam );
}

.) 在主框架的末尾设置窗口挂钩 ::OnCreate

m_detectIdleHook = (HOOKPROC)SetWindowsHookEx( WH_FOREGROUNDIDLE, 
                                         OnForeGroundIdle,
                                         NULL,
                                         ::GetCurrentThreadId());

.) 完成后,在主框架解构器中解开窗口

UnhookWindowsHookEx((HHOOK)m_detectIdleHook);

如果应用程序未处于活动状态(另一个应用程序具有焦点),这些解决方案都不会起作用。我在这里看到的唯一解决方案是使用 WM_TIMER 并通过 WaitForInputIdle (http://msdn.microsoft.com/en-us/library/ms687022%28VS.85%29.aspx) 检查空闲状态,但这会引入一定的轮询间隔可靠性。

来源:

-本页

-http://www.drdobbs.com/184416462

-http://www.codeguru.com/forum/showthread.php?t=199148

-http://www.codeproject.com/KB/dialog/idledialog.aspx?msg=770930

【讨论】:

  • 附注看起来这个主题在 vista/win7 中变得更加困难,因为 SetWindowsHookEx 显然需要高权限 (UAC)。
猜你喜欢
  • 1970-01-01
  • 2011-11-27
  • 1970-01-01
  • 2011-02-16
  • 2015-09-15
  • 1970-01-01
  • 1970-01-01
  • 2011-03-06
  • 2011-05-05
相关资源
最近更新 更多