2

Windows 有一个内部机制,通过检查用户交互性和其他任务(有人正在观看视频等)来决定何时显示屏幕保护程序(或关闭屏幕)。

是否有一个 Win API 允许我询问用户是否处于活动状态,或者他们最后一次处于活动状态是什么时候?

4

2 回答 2

6

它被称为“空闲计时器”。您可以通过调用CallNtPowerInformation()来获取它的值,询问 SystemPowerInformation。返回的 SYSTEM_POWER_INFORMATION.TimeRemaining 字段告诉您空闲计时器还剩多少时间。SystemExecutionState 请求会告诉您是否有任何线程调用 SetThreadExecutionState() 来停止计时器,就像显示视频的应用程序所做的那样。

using System;
using System.Runtime.InteropServices;

public static class PowerInfo {
    public static int GetIdleTimeRemaining() {
        var info = new SYSTEM_POWER_INFORMATION();
        int ret = GetSystemPowerInformation(SystemPowerInformation, IntPtr.Zero, 0, out info, Marshal.SizeOf(info));
        if (ret != 0) throw new System.ComponentModel.Win32Exception(ret);
        return info.TimeRemaining;
    }

    public static int GetExecutionState() {
        int state = 0;
        int ret = GetSystemExecutionState(SystemExecutionState, IntPtr.Zero, 0, out state, 4);
        if (ret != 0) throw new System.ComponentModel.Win32Exception(ret);
        return state;
    }

    private struct SYSTEM_POWER_INFORMATION {
        public int MaxIdlenessAllowed;
        public int Idleness;
        public int TimeRemaining;
        public byte CoolingMode;
    }
    private const int SystemPowerInformation = 12;
    private const int SystemExecutionState = 16;
    [DllImport("powrprof.dll", EntryPoint = "CallNtPowerInformation", CharSet = CharSet.Auto)]
    private static extern int GetSystemPowerInformation(int level, IntPtr inpbuf, int inpbuflen, out SYSTEM_POWER_INFORMATION info, int outbuflen);
    [DllImport("powrprof.dll", EntryPoint = "CallNtPowerInformation", CharSet = CharSet.Auto)]
    private static extern int GetSystemExecutionState(int level, IntPtr inpbuf, int inpbuflen, out int state, int outbuflen);

}
于 2012-06-10T17:28:42.030 回答
0

您应该看一下GetLastInputInfo函数,它返回一个结构,其中包含上次用户输入的滴答计数,一个滴答为 1 毫秒。然后,您可以将其与Environment.TickCount返回的值进行比较,以获取自上次用户输入以来经过的时间(以毫秒为单位)。

此函数的 AP/Invoke 定义可在此处获得:http ://www.pinvoke.net/default.aspx/user32.GetLastInputInfo

但请注意,由于返回的值是无符号整数,并且 TickCount 是有符号的,因此返回的刻度值GetLastInputInfo在 50 天之内返回零,但在 25 天之内返回。在大多数情况下,这可能不是什么大问题,但值得记住的是,有时可能会出现一些奇怪的行为,大约每月一次。Environment.TickCountGetLastInputInfo

于 2012-06-10T17:22:39.750 回答