El gancho del teclado y el mouse es lo que considero más valioso. La clase a continuación se puede insertar y solo tiene que averiguar qué desea hacer con la información sobre las actualizaciones de teclas y mouse.
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);
}
}
}
Por supuesto, esto solo funciona dentro de la aplicación que está conectando. Si necesita rastrear la inactividad en todo el sistema, debe crear una DLL que pueda cargarse en los espacios de direcciones de todas las demás ventanas. Lamentablemente, no he oído hablar de ningún hack que permita un .dll compilado en .net que funcione en este escenario; tenemos una DLL de C++ que se engancha con este propósito.
Tenga en cuenta que el valor int devuelto es un valor en segundos, que no se ve inmediatamente antes. (Personalmente llamaría a la función SecondsSinceLastInput o similar) – Gareth
Hice esto y luego usé psexec para enviarlo a una máquina remota a mi colega. Muestra más de 2000 segundos y aumenta. Y lo veo usando su computadora por lo que es engañoso. Parece estar mostrando más bien el tiempo desde que se encendió la máquina. – fjleon