Detectar hora da última interação do usuário com o sistema operacional

Estou escrevendo um aplicativo de bandeja pequena que precisa detectar a última vez que um usuário interagiu com a máquina para determinar se está ocioso.

Existe alguma maneira de recuperar a hora em que um usuário moveu o mouse pela última vez, pressionou uma tecla ou interagiu de alguma forma com a máquina?

Eu acho que o Windows obviamente rastreia isso para determinar quando exibir uma proteção de canvas ou desligar, etc, então eu estou supondo que há uma API do Windows para recuperar isso sozinho?

GetLastInputInfo . Documentado no PInvoke.net .

incluem os seguintes namespaces

using System; using System.Runtime.InteropServices; 

e depois include seguinte

 internal struct LASTINPUTINFO { public uint cbSize; public uint dwTime; } ///  /// Helps to find the idle time, (in milliseconds) spent since the last user input ///  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); } ///  /// Get the Last input time in milliseconds ///  ///  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; } } 

Para converter o contador em tempo, você pode usar

 TimeSpan timespent = TimeSpan.FromMilliseconds(ticks); 

Nota. Essa rotina usa o termo TickCount, mas os valores estão em milissegundos e não são os mesmos que os Ticks.

Do artigo do MSDN sobre Environment.TickCount

Obtém o número de milissegundos decorridos desde o início do sistema.

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