C # - определение времени последнего взаимодействия пользователя с ОС

Я пишу небольшое приложение на панели задач, которое должно определять, когда пользователь в последний раз взаимодействовал со своим компьютером, чтобы определить, не бездействует ли он.

Есть ли способ узнать время, когда пользователь в последний раз перемещал мышь, нажимал клавишу или каким-либо образом взаимодействовал со своей машиной?

Я полагаю, что Windows, очевидно, отслеживает это, чтобы определить, когда отображать заставку или отключение питания и т. Д., Поэтому я предполагаю, что есть Windows API для получения этого самостоятельно?


person djdd87    schedule 24.06.2009    source источник


Ответы (3)


GetLastInputInfo. Документировано на PInvoke.net.

person Matthew Flaschen    schedule 24.06.2009
comment
+1 для PInvoke.net - до сих пор не знал об этом ресурсе. - person John K; 16.06.2010
comment
не работает для сенсорных экранов без активности мыши и клавиатуры - person Smith; 26.07.2017

включить следующие пространства имен

using System;
using System.Runtime.InteropServices;

а затем включить следующие

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

Чтобы преобразовать счетчик тиков во время, вы можете использовать

TimeSpan timespent = TimeSpan.FromMilliseconds(ticks);

Примечание. В этой подпрограмме используется термин TickCount, но значения указаны в миллисекундах и поэтому не совпадают с Ticks.

Из Статья MSDN о Environment.TickCount

Получает количество миллисекунд, прошедших с момента запуска системы.

person Sriwantha Attanayake    schedule 10.08.2012
comment
Вы получаете время простоя в миллисекундах, а не в тиках. - person kennyzx; 15.09.2012
comment
Как упоминает kennyzx, правильный способ получить временной интервал TimeSpan timespent = TimeSpan.FromMilliseconds(ticks); - person Petr; 07.06.2016
comment
Когда я создаю класс, я не могу получить какие-либо объекты из класса для установки значения. Можете ли вы опубликовать пример того, как вы бы использовали это после создания экземпляра класса? - person Bbb; 06.11.2017

Код:

 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;
    }
person Luciano Rodrigues Nunes Mendes    schedule 27.12.2016