Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何检测Winforms应用程序已闲置一定时间_C#_.net_Winforms - Fatal编程技术网

C# 如何检测Winforms应用程序已闲置一定时间

C# 如何检测Winforms应用程序已闲置一定时间,c#,.net,winforms,C#,.net,Winforms,检测C#Winforms应用程序是否已闲置一段时间的最佳方法是什么 如果用户决定使用ALT+TAB并在30分钟内使用Microsoft Word或其他软件进行一些工作,而不使用我们的应用程序,我希望我们的应用程序自行终止 这是一个类似问题的公认答案: 但是,答案与Windows闲置一段时间有关,而不是特定应用程序。我希望我们的应用程序终止,如果它没有被使用的话,比如说,30分钟 我看了这个, 然而,我在评论中看到,这不适用于多线程应用程序,我们的应用程序就是其中之一我们的应用程序有一个主窗体

检测C#Winforms应用程序是否已闲置一段时间的最佳方法是什么

如果用户决定使用ALT+TAB并在30分钟内使用Microsoft Word或其他软件进行一些工作,而不使用我们的应用程序,我希望我们的应用程序自行终止

这是一个类似问题的公认答案:

但是,答案与Windows闲置一段时间有关,而不是特定应用程序。我希望我们的应用程序终止,如果它没有被使用的话,比如说,30分钟

我看了这个,

然而,我在评论中看到,这不适用于多线程应用程序,我们的应用程序就是其中之一我们的应用程序有一个主窗体,生成模态和非模态窗体,使用异步等待填充网格等。

然后我看了看SetWindowsHookEx,不确定这是否有效

肯定有人有解决方案(希望与.NET4.5兼容):)


TIA

您需要决定“空闲”的含义。我假设应用程序在所需时间内没有收到鼠标或按键输入

您可以添加一个消息过滤器,以查看所有应用程序范围的Windows消息。看见检查按键和鼠标按下的消息代码,并记录它们最后一次出现的时间,但返回false,以便运行时正常处理所有消息。可能的代码为:

WM_LBUTTONDOWN = 513
RBUTTONDOWN = 516
WM_KEYDOWN = 256
然后在另一个计时器中检查最后一个事件是在30分钟前


“终止”应用程序也存在潜在问题。如果应用程序打开了模态表单,听起来它可能不是一个特别安全的状态来突然终止。

有很多方法可以做到这一点,答案多少取决于您需要做什么。你对自己需要的东西很清楚,很具体。以下是我开发的可能符合您要求的内容。它正在使用Application.Idle来确定应用程序何时完成消息处理,然后设置计时器并过滤(侦听)应用程序的所有消息,如果收到相关消息(如鼠标或键盘),则重置计时器。它忽略鼠标移动,因为可以在不使用应用程序的情况下将鼠标移动到应用程序上。我写这篇文章已经有一段时间了,所以我不确定细节,但如果有必要,我可以弄清楚。请注意,这是一个控制台程序,可以使示例更易于尝试,但代码是用于表单应用程序的

using System;
using System.Security.Permissions;
using System.Windows.Forms;

namespace _121414
{
    static class Program
    {
        public static Timer IdleTimer = new Timer();
        const int MinuteMicroseconds = 60000;
        static Form1 f = null;

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            LeaveIdleMessageFilter limf = new LeaveIdleMessageFilter();
            Application.AddMessageFilter(limf);
            Application.Idle += new EventHandler(Application_Idle);
            IdleTimer.Interval = MinuteMicroseconds;    // One minute; change as needed
            IdleTimer.Tick += TimeDone;
            IdleTimer.Start();
            f = new Form1();
            Application.Run(f);
            Application.Idle -= new EventHandler(Application_Idle);
        }

        static private void Application_Idle(Object sender, EventArgs e)
        {
            if (!IdleTimer.Enabled)     // not yet idling?
                IdleTimer.Start();
        }

        static private void TimeDone(object sender, EventArgs e)
        {
            IdleTimer.Stop();   // not really necessary
            MessageBox.Show("Auto logoff");
            f.Close();
        }

    }

    [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
    public class LeaveIdleMessageFilter : IMessageFilter
    {
        const int WM_NCLBUTTONDOWN = 0x00A1;
        const int WM_NCLBUTTONUP = 0x00A2;
        const int WM_NCRBUTTONDOWN = 0x00A4;
        const int WM_NCRBUTTONUP = 0x00A5;
        const int WM_NCMBUTTONDOWN = 0x00A7;
        const int WM_NCMBUTTONUP = 0x00A8;
        const int WM_NCXBUTTONDOWN = 0x00AB;
        const int WM_NCXBUTTONUP = 0x00AC;
        const int WM_KEYDOWN = 0x0100;
        const int WM_KEYUP = 0x0101;
        const int WM_MOUSEMOVE = 0x0200;
        const int WM_LBUTTONDOWN = 0x0201;
        const int WM_LBUTTONUP = 0x0202;
        const int WM_RBUTTONDOWN = 0x0204;
        const int WM_RBUTTONUP = 0x0205;
        const int WM_MBUTTONDOWN = 0x0207;
        const int WM_MBUTTONUP = 0x0208;
        const int WM_XBUTTONDOWN = 0x020B;
        const int WM_XBUTTONUP = 0x020C;

        // The Messages array must be sorted due to use of Array.BinarySearch
        static int[] Messages = new int[] {WM_NCLBUTTONDOWN,
            WM_NCLBUTTONUP, WM_NCRBUTTONDOWN, WM_NCRBUTTONUP, WM_NCMBUTTONDOWN,
            WM_NCMBUTTONUP, WM_NCXBUTTONDOWN, WM_NCXBUTTONUP, WM_KEYDOWN, WM_KEYUP,
            WM_LBUTTONDOWN, WM_LBUTTONUP, WM_RBUTTONDOWN, WM_RBUTTONUP,
            WM_MBUTTONDOWN, WM_MBUTTONUP, WM_XBUTTONDOWN, WM_XBUTTONUP};

        public bool PreFilterMessage(ref Message m)
        {
            if (m.Msg == WM_MOUSEMOVE)  // mouse move is high volume
                return false;
            if (!Program.IdleTimer.Enabled)     // idling?
                return false;           // No
            if (Array.BinarySearch(Messages, m.Msg) >= 0)
                Program.IdleTimer.Stop();
            return false;
        }
    }
}
使用系统;
使用System.Security.Permissions;
使用System.Windows.Forms;
名称空间_121414
{
静态类程序
{
公共静态计时器IdleTimer=new Timer();
常数int分钟微秒=60000;
静态Form1 f=null;
/// 
///应用程序的主要入口点。
/// 
[状态线程]
静态void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
LeaveIdleMessageFilter limf=新的LeaveIdleMessageFilter();
Application.AddMessageFilter(limf);
Application.Idle+=新的事件处理程序(Application\u Idle);
IdleTimer.Interval=MinuteMicroseconds;//一分钟;根据需要更改
IdleTimer.Tick+=TimeDone;
IdleTimer.Start();
f=新的Form1();
应用程序。运行(f);
Application.Idle-=新事件处理程序(Application\u Idle);
}
静态私有void应用程序\u Idle(对象发送方、事件参数e)
{
如果(!IdleTimer.Enabled)//尚未怠速?
IdleTimer.Start();
}
静态私有void TimeDone(对象发送方、事件参数e)
{
IdleTimer.Stop();//实际上不需要
MessageBox.Show(“自动注销”);
f、 Close();
}
}
[SecurityPermission(SecurityAction.LinkDemand,Flags=SecurityPermissionFlag.UnmanagedCode)]
公共类LeaveIdleMessageFilter:IMessageFilter
{
常量int WM_nclubuttondown=0x00A1;
常量int WM_nup=0x00A2;
常量int WM_NCRBUTTONDOWN=0x00A4;
常量int WM_ncruttonup=0x00A5;
常数int WM_ncmbutdown=0x00A7;
常数int WM_NCMBUTTONUP=0x00A8;
常数int WM_NCXBUTTONDOWN=0x00AB;
常数int WM_NCXBUTTONUP=0x00AC;
常量int WM_KEYDOWN=0x0100;
常数int WM_KEYUP=0x0101;
常量int WM_MOUSEMOVE=0x0200;
常数int WM_LBUTTONDOWN=0x0201;
常量int WM_LBUTTONUP=0x0202;
常数int WM_RBUTTONDOWN=0x0204;
常数int WM_RBUTTONUP=0x0205;
常数int WM_mbutdondown=0x0207;
常数int WM_MBUTTONUP=0x0208;
常数int WM_XBUTTONDOWN=0x020B;
常数int WM_XBUTTONUP=0x020C;
//由于使用array.BinarySearch,必须对消息数组进行排序
静态int[]消息=新int[]{WM_nclu buttondown,
WM_ncluttonnup,WM_ncluttonnown,WM_ncluttonnup,WM_NCMBUTTONDOWN,
WM_NCMBUTTONUP、WM_NCXBUTTONDOWN、WM_NCXBUTTONUP、WM_KEYDOWN、WM_KEYDOWN、WM_keydup、,
WM_lbuttonown,WM_LBUTTONUP,WM_rbuttonown,WM_RBUTTONUP,
WM_mbuttonown、WM_MBUTTONUP、WM_xbuttonown、WM_XBUTTONUP};
公共bool预过滤器消息(参考消息m)
{
如果(m.Msg==WM_MOUSEMOVE)//鼠标移动量大
返回false;
如果(!Program.IdleTimer.Enabled)//空闲?
返回false;//否
if(Array.BinarySearch(Messages,m.Msg)>=0)
Program.IdleTimer.Stop();
返回false;
}
}
}

Winform onfocus lost可与计时器结合使用。您需要使用性能计数器来测量它,然后根据需要的数字来决定