Windows 系统空闲时间计算和 C# 代码中的总空闲时间?

Windows system idle time calculations and total of time duration idle in c# code?

为用户 activity 进程开发了 windows 应用程序。需要使用 c# 应用程序计算用户未使用系统的时间以及使用系统的时间以提高工作性能。我正在使用遵循代码但没有收到正确的空闲时间和持续时间值。谁能帮我解决这个问题。

       public class clsAttendance
       {        
        int _IdleCount = 0;
       

        [DllImport("user32.dll")]
        static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

        public clsAttendance()
        {
            _clsData = new clsDataConnection();
        }    


        public uint GetIdleTime()
        {
            LASTINPUTINFO lastInPut = new LASTINPUTINFO();
            lastInPut.cbSize = 
        (uint)System.Runtime.InteropServices.Marshal.SizeOf(lastInPut);
            GetLastInputInfo(ref lastInPut);

            return ((uint)Environment.TickCount - lastInPut.dwTime);
        }

        public uint GetLastInputTime()
        {
            uint idleTime = 0;
            LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
            lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo);
            lastInputInfo.dwTime = 0;

            uint envTicks = (uint)Environment.TickCount;

            if (GetLastInputInfo(ref lastInputInfo))
            {
                uint lastInputTick = lastInputInfo.dwTime;

                idleTime = envTicks - lastInputTick;
            }

            return ((idleTime > 0) ? (idleTime / 1000) : 0);
        }
               
    }

    internal struct LASTINPUTINFO
    {
        public uint cbSize;

        public uint dwTime;
    }


private void Form1_Load(object sender, EventArgs e)
        {
     a = new Timer();
         a.Tick += A_Tick;
         a.Interval = 10 * 60 * 1000;
         a.Start();

    }

 private void A_Tick(object sender, EventArgs e)
        {         

            ExceptionLogger.WriteErrorLog($"Current time: {DateTimeOffset.Now}");

            ExceptionLogger.WriteErrorLog($"Last input time without timespan: {  clsSystemIdle.GetLastInputTime()}");

            ExceptionLogger.WriteErrorLog($"Idle time without timespan: {_clsAtt.GetIdleTime()}");

            ExceptionLogger.WriteErrorLog(Message: $"Last Input TimeSpan Minutes : {TimeSpan.FromMilliseconds(clsSystemIdle.GetLastInputTime())}");

            ExceptionLogger.WriteErrorLog(Message: $"Idle TimeSpan Minutes : {TimeSpan.FromMilliseconds(_clsAtt.GetIdleTime())}");

        }

最后 40 分钟没有使用键盘和鼠标,然后返回以下输出,

当前时间:2022 年 3 月 4 日 1:49:59 下午 +05:30 没有时间跨度的上次输入时间:125 没有时间跨度的空闲时间:125266 最后输入时间跨度:00:00:00.1250000 空闲时间跨度:00:02:05.3440000

当前时间:2022 年 3 月 4 日 1:59:59 下午 +05:30 没有时间跨度的最后输入时间:22 没有时间跨度的空闲时间:22203 最后输入时间跨度:00:00:00.0220000 空闲时间跨度:00:00:22.2810000

当前时间:2022 年 3 月 4 日 2:09:59 下午 +05:30 没有时间跨度的最后输入时间:101 没有时间跨度的空闲时间:101329 最后输入时间跨度:00:00:00.1010000 空闲时间跨度:00:01:41.4380000

当前时间:2022 年 3 月 4 日 2:19:59 下午 +05:30 没有时间跨度的上次输入时间:3 没有时间跨度的空闲时间:3172 最后输入时间跨度:00:00:00.0030000 空闲时间跨度:00:00:03.1720000

这里我想要最后 40 分钟的系统空闲,但是如何从上面的返回值中获取 40 分钟的值并打印异常日志文件。请告诉我如何解决这个任务。

首先,您有两种方法,GetIdleTimeGetLastInputTime。它们几乎相同,只是前者 return 以毫秒为单位的空闲时间而后者 return 以秒为单位 idleTime / 1000。您只需要以下内容即可获得空闲时间。

public class SomeClass
{
    public static uint GetIdleTime()
    {
        var info = new LASTINPUTINFO();

        info.cbSize = (uint)Marshal.SizeOf(info);

        return GetLastInputInfo(ref info)
            ? (uint)Environment.TickCount - info.dwTime
            : 0;
    }

    [StructLayout(LayoutKind.Sequential)]
    struct LASTINPUTINFO
    {
        [MarshalAs(UnmanagedType.U4)]
        public uint cbSize;
        [MarshalAs(UnmanagedType.U4)]
        public uint dwTime;
    }

    [DllImport("user32.dll")]
    private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);
}

其次,你说过:

Last 40 minutes not using keyboard and mouse, then returned output below...

从您的测试结果来看,这是不准确的,因为空闲时间没有按预期增加。 (您分别有 125266、22203、101329 和 3172)这意味着在此期间通过输入设备或代码多次打破 user-idle 状态。否则,GetIdleTime 方法应该 return 2,400,000 毫秒(40 分钟)。

第三,考虑以下代码片段。

// Get and print the idle time in milliseconds...
var it = SomeClass.GetIdleTime();
Console.WriteLine(it);

// Create and print a TimeSpan...
var itTimeSpan = TimeSpan.FromMilliseconds(it)
Console.WriteLine(itTimeSpan.ToString("hh\:mm\:ss"));

// Get and print the last input DateTime...
var lastInputTime = DateTime.Now.AddMilliseconds(-it); // Or DateTimeOffset...
Console.WriteLine(lastInputTime);
// Or
Console.WriteLine(lastInputTime.ToString("hh:mm:ss"));