简体   繁体   English

如何确定 C# 应用程序的空闲时间?

[英]How do I determine idle time in my C# application?

I want to get the Windows Idle Time from my application.我想从我的应用程序中获取 Windows 空闲时间。 I am using exactly this code:我正在使用这个代码:

http://dataerror.blogspot.de/2005/02/detect-windows-idle-time.html http://dataerror.blogspot.de/2005/02/detect-windows-idle-time.html

I have tested this on Windows 7 and it is working properly, but I am getting only a zero on Windows 8.我已经在 Windows 7 上测试过它并且它工作正常,但我在 Windows 8 上只得到零。

Any ideas how to fix this?任何想法如何解决这一问题?

I took a slightly different approach to your method... This determines the idle time for your application, rather than using the system-wide idle time.我对你的方法采取了稍微不同的方法......这决定了你的应用程序的空闲时间,而不是使用系统范围的空闲时间。 I'm not sure if this meets your needs, however it might help you get further.我不确定这是否满足您的需求,但它可能会帮助您更进一步。 It also has the benefit of being pure .NET instead of using DllImport .它还具有纯 .NET 而不是使用DllImport的好处。

public partial class MyForm : Form, IMessageFilter {

    private Timer _timer;

    // we only need one of these methods...
    private DateTime _wentIdle;
    private int _idleTicks;

    public MyForm() {

        // watch for idle events and any message that might break idle
        Application.Idle += new EventHandler(Application_OnIdle);
        Application.AddMessageFilter(this);

        // use a simple timer to watch for the idle state
        _timer = new Timer();
        _timer.Tick += new EventHandler(Timer_Exipred);
        _timer.Interval = 1000;
        _timer.Start();

        InitializeComponent();
    }

    private void Timer_Exipred(object sender, EventArgs e) {
        TimeSpan diff = DateTime.Now - _wentIdle;

        // see if we have been idle longer than our configured value
        if (diff.TotalSeconds >= Settings.Default.IdleTimeout_Sec) {
            _statusLbl.Text = "We Are IDLE! - " + _wentIdle;
        }

        /**  OR  **/

        // see if we have gone idle based on our configured value
        if (++_idleTicks >= Settings.Default.IdleTimeout_Sec) {
            _statusLbl.Text = "We Are IDLE! - " + _idleTicks;
        }
    }

    private void Application_OnIdle(object sender, EventArgs e) {
        // keep track of the last time we went idle
        _wentIdle = DateTime.Now;
    }

    public bool PreFilterMessage(ref Message m) {
        // reset our last idle time if the message was user input
        if (isUserInput(m)) {
            _wentIdle = DateTime.MaxValue;
            _idleTicks = 0;

            _statusLbl.Text = "We Are NOT idle!";
        }

        return false;
    }

    private bool isUserInput(Message m) {
        // look for any message that was the result of user input
        if (m.Msg == 0x200) { return true; } // WM_MOUSEMOVE
        if (m.Msg == 0x020A) { return true; } // WM_MOUSEWHEEL
        if (m.Msg == 0x100) { return true; } // WM_KEYDOWN
        if (m.Msg == 0x101) { return true; } // WM_KEYUP

        // ... etc

        return false;
    }
}

I really have two methods for determining idle here... One using a DateTime object and one using a simple counter.我真的有两种方法可以在这里确定空闲...一种使用DateTime对象,另一种使用简单的计数器。 You may find that one of these is better suited for your needs.您可能会发现其中一种更适合您的需求。

For the list of messages you may want to consider as user input, visit here .有关您可能希望作为用户输入考虑的消息列表,请访问此处

    protected override void OnLoad(EventArgs e)
    {
    /* Check if we are in idle mode - No mouse movement for 2 minutes */
    System.Windows.Forms.Timer CheckIdleTimer = new                    System.Windows.Forms.Timer();
    CheckIdleTimer.Interval = 120000;
    CheckIdleTimer.Tick += new EventHandler(CheckIdleTimer_Tick);
    CheckIdleTimer.Start();
    }
    private void CheckIdleTimer_Tick(object sender, EventArgs e)
    {
    uint x = IdleTimeFinder.GetIdleTime();
    if (x > 120000) {
         //...do something
    }
    }


    public class IdleTimeFinder
    {
    [DllImport("User32.dll")]
    private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

    [DllImport("Kernel32.dll")]
    private static extern uint GetLastError();

    public static 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 static long GetLastInputTime()
   {
    LASTINPUTINFO lastInPut = new LASTINPUTINFO();
    lastInPut.cbSize                (uint)System.Runtime.InteropServices.Marshal.SizeOf(lastInPut);
    if (!GetLastInputInfo(ref lastInPut))
    {
    throw new Exception(GetLastError().ToString());
    }
    return lastInPut.dwTime;
    }
    }


 internal struct LASTINPUTINFO
{
    public uint cbSize;

    public uint dwTime;
}

Here is a sample code of how you can detect idle time in Windows.以下是如何检测 Windows 中的空闲时间的示例代码。 The definition of idle time here refer to the time when there is no user interaction with Windows such as no keyboard and mouse input.这里的空闲时间定义是指没有用户与 Windows 交互(例如没有键盘和鼠标输入)的时间。

Detecting idle time is used in application like MSN Messenger to change the status to "Away" after the user does not interact with the Windows for a predefine time.检测空闲时间用于 MSN Messenger 等应用程序中,以便在用户在预定义时间内未与 Windows 交互后将状态更改为“离开”。

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace GetLastInput_Demo
{
    /// <summary>
    /// Summary description for Form1.
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        [DllImport("user32.dll")]
        static extern bool GetLastInputInfo(out LASTINPUTINFO plii);

        [StructLayout( LayoutKind.Sequential )]
        struct LASTINPUTINFO
        {
            public static readonly int SizeOf =
                   Marshal.SizeOf(typeof(LASTINPUTINFO));

            [MarshalAs(UnmanagedType.U4)]
            public int cbSize;   
            [MarshalAs(UnmanagedType.U4)]
            public int dwTime;
        }

        private System.Windows.Forms.Button button1;
        private System.Windows.Forms.Label label1;
        private System.Windows.Forms.Timer timer1;
        private System.ComponentModel.IContainer components;

        public Form1()
        {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();

        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }
        #region Windows Form Designer generated code
        private void InitializeComponent()
        {
            // Code is omitted here.
        }
        #endregion

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.Run(new Form1());
        }

        private void button1_Click(object sender, System.EventArgs e)
        {
            timer1.Enabled = !timer1.Enabled;
        }

        private void timer1_Tick(object sender, System.EventArgs e)
        {
            int idleTime = 0;
            LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
            lastInputInfo.cbSize = Marshal.SizeOf( lastInputInfo );
            lastInputInfo.dwTime = 0;

            int envTicks = Environment.TickCount;

            if( GetLastInputInfo( out lastInputInfo ) )
            {
                int lastInputTick = lastInputInfo.dwTime;
                idleTime = envTicks - lastInputTick;
            }

            int a;
           
            if(idleTime > 0)
               a = idleTime / 1000;
            else
               a = idleTime;

            label1.Text = a.ToString();
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM