using System; using System.Runtime.InteropServices; namespace TimerApp { public static class NativeMethods { [StructLayout(LayoutKind.Sequential)] struct LASTINPUTINFO { public static readonly int SizeOf = Marshal.SizeOf(typeof(LASTINPUTINFO)); [MarshalAs(UnmanagedType.U4)] public UInt32 cbSize; [MarshalAs(UnmanagedType.U4)] public UInt32 dwTime; } [DllImport("user32.dll")] static extern bool GetLastInputInfo(ref LASTINPUTINFO plii); /// /// 获取系统空闲时间(毫秒) /// /// public static long GetIdleTime() { LASTINPUTINFO lastInputInfo = new LASTINPUTINFO(); lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo); lastInputInfo.dwTime = 0; if (GetLastInputInfo(ref lastInputInfo)) { // Environment.TickCount 可能会在大约 24.9 天后翻转为负数, // 但 GetLastInputInfo 返回的也是 uint (DWORD),所以我们统一转为 long 处理差值 // 或者直接使用 unchecked 减法处理溢出 // 更稳健的做法是使用 GetTickCount64 (Vista+),但 Environment.TickCount 在 .NET Core 3.1+ 已经是 64位了(Environment.TickCount64) // 这里为了兼容性,我们简单处理。注意 GetLastInputInfo 返回的是 uint 毫秒数。 long envTicks = Environment.TickCount; // 处理 TickCount 翻转问题 (Environment.TickCount 是 int,GetLastInputInfo 是 uint) // 简单的做法: return (long)GetTickCount() - (long)lastInputInfo.dwTime; } return 0; } [DllImport("kernel32.dll")] static extern uint GetTickCount(); } }