C# - Detect time of last user interaction with the OS

C#WindowsWinapiSystem TrayIdle Processing

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questiondjdd87View Question on Stackoverflow
Solution 1 - C#Matthew FlaschenView Answer on Stackoverflow
Solution 2 - C#Sriwantha AttanayakeView Answer on Stackoverflow
Solution 3 - C#Luciano Rodrigues Nunes MendesView Answer on Stackoverflow