C# - Detect time of last user interaction with the OS
C#WindowsWinapiSystem TrayIdle ProcessingC# Problem Overview
I'm writing a small tray application that needs to detect the last time a user interacted with their machine to determine if they're idle.
Is there any way to retrieve the time a user last moved their mouse, hit a key or interacted in any way with their machine?
I figure Windows obviously tracks this to determine when to display a screen saver or power down, etc, so I'm assuming there's a Windows API for retrieving this myself?
C# Solutions
Solution 1 - C#
GetLastInputInfo. Documented at PInvoke.net.
Solution 2 - C#
include following namespaces
using System;
using System.Runtime.InteropServices;
and then include following
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;
}
}
To convert the tickcount into time you can use
TimeSpan timespent = TimeSpan.FromMilliseconds(ticks);
Note. This routine uses the term TickCount but the values are in milliseconds and are so not the same as Ticks.
From MSDN article on Environment.TickCount > Gets the number of milliseconds elapsed since the system started.
Solution 3 - C#
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;
}