2009-06-24 27 views
54

J'écris une petite application de bac qui doit détecter la dernière fois qu'un utilisateur a interagi avec son ordinateur pour déterminer s'il est inactif.C# - Détecter l'heure de l'interaction du dernier utilisateur avec le système d'exploitation

Existe-t-il un moyen de récupérer le moment où un utilisateur a bougé sa souris, touché une touche ou interagi de quelque façon que ce soit avec sa machine? Je suppose que Windows suit cela pour déterminer quand afficher un économiseur d'écran ou mettre hors tension, etc, donc je suppose qu'il y a une API Windows pour récupérer moi-même?

Répondre

60

GetLastInputInfo. Documenté au PInvoke.net.

+2

Parfait, je vous remercie. – GenericTypeTea

+4

+1 pour PInvoke.net - Je ne connaissais pas cette ressource jusqu'à maintenant. –

+0

ne fonctionne pas pour les écrans tactiles sans l'activité de la souris et du clavier – Smith

29

comprennent les espaces de noms suivants

using System; 
using System.Runtime.InteropServices; 

puis inclure ci-dessous

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; 
    } 
} 

Pour convertir la tickcount en temps, vous pouvez utiliser

TimeSpan timespent = TimeSpan.FromMilliseconds(ticks); 

Remarque. Cette routine utilise le terme TickCount mais les valeurs sont en millisecondes et ne sont donc pas les mêmes que Ticks.

De MSDN article on Environment.TickCount

Retourne le nombre de millisecondes écoulées depuis le démarrage du système.

+15

Vous obtenez le temps d'inactivité en millisecondes, pas de ticks. – kennyzx

+0

Comme kennyzx mentionne la bonne façon d'obtenir le timespan est 'TimeSpan timespent = TimeSpan.FromMilliseconds (ticks);' – Petr

+0

Lorsque je crée un cours je ne peux pas obtenir des objets hors de la classe pour définir une valeur, pouvez-vous poster un exemple de comment utiliseriez-vous cela après avoir instancié la classe? – Jay

1

code:

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; 
    }