我们使用GetLastInputInfo并计算与GetTickCount64结果的差值来确定空闲。但是,GetLastInputInfo返回的节拍计数被写入到LASTINPUTINFO的成员dwTime中,该成员是一个DWORD型,因此是一个无符号32位整数,最大值为及其最大值4294967295,相当于~49天。在正常运行时间超过这个值的机器上,这当然会导致函数报告不正确的值。
显然没有名为GetLastInputInfo64的函数,但可能有一个不同名称的函数?
发布于 2019-04-23 22:28:51
我们使用了一种变通方法。
只使用GetLastInputInfo()
的结果来检测dwTick
是否发生了变化,而不关心它发生了多大变化。
定期执行此操作。
当滴答发生变化时(数值与之前的读数不同),启动您自己的计时器,并使用该计时器来检测输入是否空闲了30秒。
使用这种方法,您将永远不需要处理环绕。
发布于 2021-02-13 21:15:11
@Anders:
public class IdleDetection
{
private struct LASTINPUTINFO
{
public uint cbSize;
public uint dwTime;
}
[DllImport("user32.dll")]
private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
private readonly Timer _idleTimer;
private double _idleSeconds = 0;
private uint _previousLastInput = 0;
private DateTime _idleStart = DateTime.Now;
private object _lock = new object();
public IdleDetection()
{
_idleTimer = new Timer(TimerCallback, null, 1000, Timeout.Infinite);
}
public TimeSpan IdleTime
{
get {
lock (_lock)
{
return TimeSpan.FromSeconds(_idleSeconds);
}
}
}
private void TimerCallback(object state)
{
lock (_lock)
{
var lastInput = GetLastInputInfoValue();
if (lastInput == _previousLastInput)
{
_idleSeconds = (DateTime.Now - _idleStart).TotalSeconds;
}
else
{
_idleSeconds = 0;
_idleStart = DateTime.Now;
}
_previousLastInput = lastInput;
}
_idleTimer.Change(1000, Timeout.Infinite);
}
private static uint GetLastInputInfoValue()
{
LASTINPUTINFO lastInPut = new LASTINPUTINFO();
lastInPut.cbSize = (uint)Marshal.SizeOf(lastInPut);
GetLastInputInfo(ref lastInPut);
return lastInPut.dwTime;
}
}
https://stackoverflow.com/questions/52531072
复制相似问题