2008-10-15 14 views
9

Varios programas pueden hacer cosas solo cuando no ha utilizado la computadora por un tiempo (por ejemplo, protector de pantalla, indexación de Google Desktop, etc.).Cómo saber cuándo Windows está inactivo

¿Cómo saben cuándo ha estado inactivo? ¿Hay alguna función en Windows que le diga cuánto tiempo ha estado inactiva, o tiene que utilizar algún tipo de gancho de teclado/mouse para realizar un seguimiento de la actividad usted mismo?

Estoy usando C#, pero estoy interesado en cualquier método para determinar la inactividad.

Respuesta

10

EDITAR: respuesta modificada, proporcionando texto y detalles detrás de la respuesta de Shy (que debe ser y fue aceptado). Siéntase libre de combinar y eliminar este.

GetLastInputInfo Función La función GetLastInputInfo recupera la hora del último evento de entrada.

pegado aquí de P/Invoke

Esta función recupera el tiempo desde la última entrada de usuario

[DllImport("user32.dll")] 
static extern bool GetLastInputInfo(ref LASTINPUTINFO plii); 

static int GetLastInputTime() 
{ 
    int idleTime = 0; 
    LASTINPUTINFO lastInputInfo = new LASTINPUTINFO(); 
    lastInputInfo.cbSize = Marshal.SizeOf(lastInputInfo); 
    lastInputInfo.dwTime = 0; 

    int envTicks = Environment.TickCount; 

    if(GetLastInputInfo(ref lastInputInfo)) 
    { 
    int lastInputTick = lastInputInfo.dwTime; 

    idleTime = envTicks - lastInputTick; 
    } 

    return ((idleTime > 0) ? (idleTime/1000) : idleTime); 
} 

[StructLayout(LayoutKind.Sequential)] 
struct LASTINPUTINFO 
{ 
    public static readonly int SizeOf = Marshal.SizeOf(typeof(LASTINPUTINFO)); 

    [MarshalAs(UnmanagedType.U4)] 
    public int cbSize;  
    [MarshalAs(UnmanagedType.U4)] 
    public UInt32 dwTime; 
} 

Fwiw: he implementado un gancho de teclado y ratón global durante AnAppADay. Vea esta aplicación para la fuente, está muy cerca de lo que quiere. Las clases que deseará están en el espacio de nombres AnAppADay.Utils. [rayado debido a linkrot]

+0

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

+0

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

5

Google is your friend

utiliza Básicamente this.
no se olvide de la documentación totalmente listo antes de usar.

+0

Estaba buscando "inactivo" en lugar de "inactivo". GetLastInputInfo es exactamente lo que necesitaba. Gracias. –

+0

Tenga en cuenta que es solo para la sesión actual. Puede haber otras sesiones donde los usuarios estén activos. No estoy seguro de si es posible hacer esta sesión cruzada porque podría ser una violación de seguridad. – shoosh

+0

Me pregunto por qué esto fue downvoted? ¿La única razón por la que puedo pensar es que solo tiene enlaces y ninguna respuesta real? ¿O qué pasa porque hay problemas con el uso de GetLastInputInfo? –

0

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.

+0

¿Sabía usted acerca de GetLastInputInfo? ¿Hay alguna razón por la que lo haga esto en lugar de GetLastInputInfo? –

+0

Es más complejo ;-) personas así :) – Skuta

+0

En realidad, no, no tenía conocimiento de GetLastInputInfo. Pero dado que generalmente cuando hacemos este tipo de anzuelos, no solo estamos buscando información de tiempo de espera, esa llamada sola no sería útil para nosotros. Por lo general, estamos buscando una gama más amplia de funciones de manejo de tecla y mouse. – Bill

Cuestiones relacionadas