C# - 检测上次用户与OS交互的时间

djd*_*d87 63 c# windows winapi system-tray idle-processing

我正在编写一个小托盘应用程序,需要检测用户上次与其计算机进行交互以确定它们是否处于空闲状态.

有没有办法检索用户上次移动鼠标,按键或以任何方式与他们的机器进行交互的时间?

我认为Windows显然跟踪这个以确定何时显示屏幕保护程序或断电等,所以我假设有一个Windows API用于自己检索这个?

Mat*_*hen 65

GetLastInputInfo.在PInvoke.net上记录.

  • PInvoke.net为+1 - 直到现在我才知道该资源. (6认同)
  • 不适用于没有鼠标和键盘活动的触摸屏 (2认同)

Sri*_*ake 41

包括以下命名空间

using System;
using System.Runtime.InteropServices;
Run Code Online (Sandbox Code Playgroud)

然后包括以下内容

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

要将tickcount转换为可以使用的时间

TimeSpan timespent = TimeSpan.FromMilliseconds(ticks);
Run Code Online (Sandbox Code Playgroud)

注意.此例程使用术语TickCount,但值以毫秒为单位,与Ticks不同.

来自MSDN上有关Environment.TickCount的文章

获取自系统启动以来经过的毫秒数.

  • 你得到的空闲时间是毫秒,而不是滴答. (18认同)
  • 正如 kennyzx 提到的获取时间跨度的正确方法是 `TimeSpan timespent = TimeSpan.FromMilliseconds(ticks);` (2认同)