我想从我的应用程序中获取Windows空闲时间。我正在使用这段代码:
http://dataerror.blogspot.de/2005/02/detect-windows-idle-time.html
我在Windows 7上测试了它并且它运行正常,但我在Windows 8上只得到零。
任何想法如何解决这个问题?
答案 0 :(得分:9)
我对您的方法采用了稍微不同的方法......这确定了应用程序的空闲时间,而不是使用系统范围的空闲时间。我不确定这是否符合您的需求,但它可能会帮助您进一步发展。它还具有纯.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
对象,一种使用简单的计数器。您可能会发现其中一个更适合您的需求。
有关您可能需要考虑作为用户输入的邮件列表,请访问here。
答案 1 :(得分:1)
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;
}
答案 2 :(得分:1)
这是示例代码,说明如何在Windows中检测空闲时间。空闲时间的定义是指没有与Windows的用户交互(例如没有键盘和鼠标输入)的时间。
检测闲置时间用于MSN Messenger等应用程序中,以便在用户未与Windows交互预定时间后将其状态更改为“ Away”。
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();
}
}
}