Windows有一个内部机制,通过检查用户交互性和其他任务(某人正在观看视频等)来决定何时显示屏幕保护程序(或关闭屏幕)。
是否有一个Win API允许我询问用户是否处于活动状态,或者他们上次何时处于活动状态?
答案 0 :(得分: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);
}
答案 1 :(得分:0)
你应该看看GetLastInputInfo函数,该函数返回一个结构,其中包含上次用户输入的滴答计数,一个滴答为1ms。然后,您可以通过Environment.TickCount将其与值returend进行比较,以获得自上次用户输入以来经过的时间(以毫秒为单位)。
此功能的P / Invoke定义可在此处获取:http://www.pinvoke.net/default.aspx/user32.GetLastInputInfo
请注意,GetLastInputInfo
返回的刻度值在短短50天内回归到零,但Environment.TickCount
包裹的时间不到25天,因为{{1}返回的值作为unsigned int,并且TickCount被签名。在大多数情况下,这可能不是一个大问题,但值得记住的是,偶尔会有一些奇怪的行为,大约每月一次。