且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

系统空闲时间用户空闲

更新时间:2023-11-22 08:20:58

用户空闲的时间绝对与系统空闲时间不同。系统可以在没有任何用户参与的情况下随时主动工作。



要测量用户空闲时间,您需要跟踪系统范围内的鼠标和键盘活动。这样做的唯一通用方法是使用Windows Hooks:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms632589%28v=vs.85%29.aspx [ ^ ],

http: //msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx [ ^ ]。



***使用 idHook 参数进行低级键盘和鼠标事件, WH_KEYBOARD_LL WH_MOUSE_LL

ħ ttp://msdn.microsoft.com/en-us/library/windows/desktop/ms644985(v = vs.85).aspx [ ^ ],

http://msdn.microsoft.com/en-us/library /windows/desktop/ms644986(v=vs.85).aspx [ ^ ]。



您只需要检测任何单个事件和记录它的时间,你可以使用 System.DateTime.Now System.Diagnostics.Stopwatch 并测量 System.TimeSpan

http://msdn.microsoft.com/en-us/library/system.datetime.aspx [ ^ ],

http://msdn.microsoft.com/en-us/library/system.datetime.now.aspx [ ^ ],

http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch%28v=vs。 110%29.aspx [ ^ ],

http://msdn.microsoft.com/en-us/library/system.timespan%28v=vs.110%29.aspx [ ^ ]。br />


然而,这并不容易。首先,你不能在VB.NET中全部完成。问题是:您的解决方案需要一个全局挂钩。根据Microsoft的说法,您还可以仅在本机(非托管)DLL中设置全局挂钩(与进程本地挂钩相反),因此您需要使用某种本机平台语言。您可以使用P / Invoke与此DLL以及原始Windows API进行通信。请参阅:

http://en.wikipedia.org/wiki/Platform_Invocation_Services [ ^ ];

此CodeProject文章也可以有用: http://www.codeproject.com/csharp/EssentialPInvoke.asp [ ^ ]。



另一个问题是事件将被钩住是一些其他线程,所以你需要线程同步和可能的一些IPC机制,如果你在一个单独的进程中挂钩。如果您需要在某些UI中使用挂钩,则还需要将某个线程触发的代码调用到UI线程的机制。请参阅我之前关于此主题的回答:

控制.Invoke()vs. Control.BeginInvoke() [ ^ ],

Treeview扫描仪和MD5的问题 [ ^ ]。



你应该认真考虑是否值得付出努力。也许您需要仅在一个应用程序上跟踪用户活动的缺乏,这要容易很多倍。或者您可能根本不需要关注用户活动的空闲时间。所有用户都有权利在任何时候正式闲置。



为了以防万一,请同时查看我过去的答案,与之相关的讨论,以及整个主题:如何退出WIN32应用 [ ^ ]。







另请参阅我过去与Windows Hook相关的答案:

键盘挂钩如何工作以及如何实施 [ ^ ],

如何在其他应用程序中设置窗口挂钩? [ ^ ],

创建全局快捷方式。 [ ^ ]。



-SA
The time when a user being idle is absolutely not the same as system idle time. A system can actively work for anytime without any user's participation.

To measure the user idle time, you need to track system-wide mouse and keyboard activity. The only universal ways of doing so is the use of Windows Hooks:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms632589%28v=vs.85%29.aspx[^],
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx[^].

It's better to do it with idHook parameter for low-level keyboard and mouse events, WH_KEYBOARD_LL and WH_MOUSE_LL:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644985(v=vs.85).aspx[^],
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644986(v=vs.85).aspx[^].

You just need to detect any single event and record the time of it, you can use either System.DateTime.Now or System.Diagnostics.Stopwatch and measure the System.TimeSpan:
http://msdn.microsoft.com/en-us/library/system.datetime.aspx[^],
http://msdn.microsoft.com/en-us/library/system.datetime.now.aspx[^],
http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch%28v=vs.110%29.aspx[^],
http://msdn.microsoft.com/en-us/library/system.timespan%28v=vs.110%29.aspx[^].

However, it is not so easy. First of all, you cannot do it all in VB.NET along. The problem is: your solution will need a global hook. According to Microsoft, you can also set a global hook (in contrast to the process-local one) only in a native (unmanaged) DLL, so you would need to use some native-platform language. You can communicate with this DLL, as well as raw Windows API, using P/Invoke. Please see:
http://en.wikipedia.org/wiki/Platform_Invocation_Services[^];
this CodeProject article can also be useful: http://www.codeproject.com/csharp/EssentialPInvoke.asp[^].

Another problem is that the event will be hooked is some other thread, so you would need thread synchronization and possibly some IPC mechanism, if you do hooking in a separate process. If you need to work with hooking in some UI, you would also need the mechanism invoking code triggered by some thread to a UI thread. Please see my past answer on this topic:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

You should seriously think if it worth the effort or not. Maybe you need to track the lack of user activity on just one application, which is many times easier. Or maybe you don't need to take care about idle period of user activity at all. All users should have a natural right to be formally idle for any time they want.

Just in case, please also see my past answer, discussion related to it, as well as the whole thread: How to exit a WIN32 app[^].



See also my past answers related to Windows Hooks:
How the Keyboard Hook works and how it is being implemented[^],
How to set a window hook in other application?[^],
Creating global shortcuts.[^].

—SA