簡體   English   中英

如何確定 C# 應用程序的空閑時間?

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

我想從我的應用程序中獲取 Windows 空閑時間。 我正在使用這個代碼:

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

我已經在 Windows 7 上測試過它並且它工作正常,但我在 Windows 8 上只得到零。

任何想法如何解決這一問題?

我對你的方法采取了稍微不同的方法......這決定了你的應用程序的空閑時間,而不是使用系統范圍的空閑時間。 我不確定這是否滿足您的需求,但它可能會幫助您更進一步。 它還具有純 .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;
    }
}

我真的有兩種方法可以在這里確定空閑...一種使用DateTime對象,另一種使用簡單的計數器。 您可能會發現其中一種更適合您的需求。

有關您可能希望作為用戶輸入考慮的消息列表,請訪問此處

    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;
}

以下是如何檢測 Windows 中的空閑時間的示例代碼。 這里的空閑時間定義是指沒有用戶與 Windows 交互(例如沒有鍵盤和鼠標輸入)的時間。

檢測空閑時間用於 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