2009-06-24 17 views
54

Escribo una pequeña aplicación de bandeja que necesita detectar la última vez que un usuario interactuó con su máquina para determinar si están inactivos.C# - Detecta la hora de la última interacción del usuario con el sistema operativo

¿Hay alguna manera de recuperar el tiempo que un usuario movió su mouse por última vez, presionó una tecla o interactuó de alguna manera con su máquina?

Me imagino que Windows obviamente realiza un seguimiento de esto para determinar cuándo mostrar un protector de pantalla o apagado, etc., entonces supongo que hay una API de Windows para recuperarlo yo mismo?

Respuesta

60

GetLastInputInfo. Documentado en PInvoke.net.

+2

perfecto, gracias. – GenericTypeTea

+4

+1 para PInvoke.net - No sabía acerca de ese recurso hasta ahora. –

+0

no funciona para pantallas táctiles sin actividad de mouse y teclado – Smith

29

incluyen siguientes espacios de nombres

using System; 
using System.Runtime.InteropServices; 

y luego incluir siguiente

internal struct LASTINPUTINFO 
{ 
    public uint cbSize; 

    public uint dwTime; 
} 

/// <summary> 
/// Helps to find the idle time, (in milliseconds) spent since the last user input 
/// </summary> 
public class IdleTimeFinder 
{ 
    [DllImport("User32.dll")] 
    private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);   

    [DllImport("Kernel32.dll")] 
    private static extern uint GetLastError(); 

    public static uint GetIdleTime() 
    { 
     LASTINPUTINFO lastInPut = new LASTINPUTINFO(); 
     lastInPut.cbSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(lastInPut); 
     GetLastInputInfo(ref lastInPut); 

     return ((uint)Environment.TickCount - lastInPut.dwTime); 
    } 
/// <summary> 
/// Get the Last input time in milliseconds 
/// </summary> 
/// <returns></returns> 
    public static long GetLastInputTime() 
    { 
     LASTINPUTINFO lastInPut = new LASTINPUTINFO(); 
     lastInPut.cbSize = (uint)System.Runtime.InteropServices.Marshal.SizeOf(lastInPut); 
     if (!GetLastInputInfo(ref lastInPut)) 
     { 
      throw new Exception(GetLastError().ToString()); 
     }  
     return lastInPut.dwTime; 
    } 
} 

Convertir el TickCount en el tiempo se puede utilizar

TimeSpan timespent = TimeSpan.FromMilliseconds(ticks); 

Nota. Esta rutina usa el término TickCount, pero los valores están en milisegundos y no son lo mismo que Ticks.

De MSDN article on Environment.TickCount

Obtiene el número de milisegundos transcurridos desde que se inició el sistema.

+15

Obtiene el tiempo de inactividad en milisegundos, no en tics. – kennyzx

+0

Como kennyzx menciona la forma correcta de obtener el intervalo de tiempo es 'TimeSpan timespent = TimeSpan.FromMilliseconds (ticks);' – Petr

+0

Cuando creo una clase No puedo obtener ningún objeto fuera de la clase para establecer un valor, ¿puedes publicar un ejemplo de ¿Cómo usarías esto después de instanciar la clase? – Jay

1

Código:

using System; 
using System.Runtime.InteropServices; 

public static int IdleTime() //In seconds 
    { 
     LASTINPUTINFO lastinputinfo = new LASTINPUTINFO(); 
     lastinputinfo.cbSize = Marshal.SizeOf(lastinputinfo); 
     GetLastInputInfo(ref lastinputinfo); 
     return (((Environment.TickCount & int.MaxValue) - (lastinputinfo.dwTime & int.MaxValue)) & int.MaxValue)/1000; 
    } 
Cuestiones relacionadas