The keyboard and mouse hooks are what I find to be most valuable. The class below can be inserted and you just have to figure out what you want to do with the information about key and mouse updates.
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
namespace Example {
public class Hook {
delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
[FlagsAttribute]
public enum WindowMessage {
WM_KEYDOWN = 0x0000000000000100, // &H100
WM_MOUSEMOVE = 0x0000000000000200, // &H200
WM_LBUTTONDOWN = 0x0000000000000201, // &H201
WM_RBUTTONDOWN = 0x0000000000000204, // &H204
WH_KEYBOARD = 2,
WH_MOUSE = 7,
HC_ACTION = 0
}
[DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
private static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
private static extern bool UnhookWindowsHookEx(int idHook);
[DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
//Declare MouseHookProcedure as a HookProc type.
static HookProc MouseHookProcedure;
static HookProc KeyboardHookProcedure;
private static int mhMouseHook = 0;
private static int mhKeyboardHook = 0;
public Hook() {}
public static void Init() {
MouseHookProcedure = new HookProc( MouseHookProc );
KeyboardHookProcedure = new HookProc( KeyboardHookProc );
mhMouseHook = SetWindowsHookEx( (int)WindowMessage.WH_MOUSE, MouseHookProcedure, (IntPtr)0, AppDomain.GetCurrentThreadId() );
mhKeyboardHook = SetWindowsHookEx( (int)WindowMessage.WH_KEYBOARD, KeyboardHookProcedure, (IntPtr)0, AppDomain.GetCurrentThreadId() );
}
public static void Terminate() {
UnhookWindowsHookEx( mhMouseHook );
UnhookWindowsHookEx( mhKeyboardHook );
}
private static int MouseHookProc( int nCode, IntPtr wParam, IntPtr lParam ) {
if ( nCode >= 0 ) {
//do something here to update the last activity point, i.e. a keystroke was detected so reset our idle timer.
}
return CallNextHookEx( mhMouseHook, nCode, wParam, lParam );
}
private static int KeyboardHookProc( int nCode, IntPtr wParam, IntPtr lParam ) {
if ( nCode >= 0 ) {
//do something here to update the last activity point, i.e. a mouse action was detected so reset our idle timer.
}
return CallNextHookEx( mhKeyboardHook, nCode, wParam, lParam );
}
}
}
Of course this only works within the application you are hooking. If you need to track inactivity across the entire system, you need to create a DLL that can be loaded into the address spaces of all other windows. Unfortunately, I haven't heard of any hack that would allow a .net compiled .dll that will work in this scenario; we have a C++ DLL that hooks for this purpose.