2009-06-24 12 views
54

Piszę małą aplikację na tace, która musi wykryć, kiedy użytkownik po raz ostatni wchodził w interakcje z urządzeniem, aby określić, czy są bezczynne.C# - Wykryj czas ostatniej interakcji użytkownika z OS

Czy istnieje sposób na odzyskanie czasu, w którym użytkownik po raz ostatni przestawił mysz, uderzył w klawisz lub w jakikolwiek sposób nawiązał z nim interakcję?

Podejrzewam, że Windows oczywiście śledzi to, aby określić, kiedy wyświetlić wygaszacz ekranu lub wyłączyć itd., Więc zakładam, że istnieje interfejs API systemu Windows do pobierania tego samemu?

Odpowiedz

60

GetLastInputInfo. Dokumentacja pod numerem PInvoke.net.

+2

Perfect, dziękuję. – GenericTypeTea

+4

+1 dla PInvoke.net - do tej pory nie znałem tego zasobu. –

+0

nie działa na ekranach dotykowych bez aktywności myszy i klawiatury. – Smith

29

obejmują następujące obszary nazw

using System; 
using System.Runtime.InteropServices; 

a następnie dołączyć następujące

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

Aby przekonwertować tickcount do czasu można użyć

TimeSpan timespent = TimeSpan.FromMilliseconds(ticks); 

Note. Ta procedura używa terminu TickCount, ale wartości są podawane w milisekundach i nie są takie same jak w przypadku funkcji Ticks.

Od MSDN article on Environment.TickCount

Pobiera liczbę milisekund, które upłynęły od systemu zaczęło.

+15

Otrzymujesz czas bezczynności w milisekundach, a nie tyknięcia. – kennyzx

+0

Jako że kennozx wspomina o prawidłowym sposobie uzyskania przedziału czasowego jest 'Timespan timespent = TimeSpan.FromMilliseconds (ticks);' – Petr

+0

Kiedy tworzę klasę, nie mogę uzyskać żadnych obiektów poza klasą, aby ustawić wartość, czy możesz zamieścić przykład w jaki sposób możesz użyć tego po utworzeniu klasy? – Jay

1

Kod:

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; 
    } 
Powiązane problemy