定时器停止后重新启动InActivity Monitor

时间:2018-06-08 00:48:56

标签: c# .net winforms

我有WinForms应用程序,我正在使用以下帖子中的代码来检查我的应用程序的InActivity状态(请参阅帖子中的接受答案)。 InActivity In WinForms。一旦应用程序达到不活动状态,它就会停止不活动监视器。但是我希望在用户登录后重新启动时间。

所以当用户登录时我有一个通知机制,我再次调用启动计时器方法。我收到了启动监视器消息,但该应用程序从不跟踪不活动状态,我根本不知道定时器报告应用程序是非活动消息。请帮忙。

 public static System.Windows.Forms.Timer IdleTimer =null;
    static int MilliSeconds = 60000;
    static void Main(string[] args)
            {
                    f = new GeneStudyForm(true, arguments.SystemTimeOutFolder, arguments.SystemTimeOutFile, StartInActivityMonitor);
                    int x = StartInActivityMonitor();
            }

        public static void StartInActivityMonitor()
        {
            IdleTimer = new Timer();
            LeaveIdleMessageFilter limf = new LeaveIdleMessageFilter();
            Application.AddMessageFilter(limf);
            IdleTimer.Interval = MilliSeconds;    //One minute; change as needed
            Application.Idle += new EventHandler(Application_Idle);
            if (IdleTimer != null)
            {
                MessageBox.Show(IdleTimer.Interval.ToString());
            }
            IdleTimer.Tick += TimeDone;
            IdleTimer.Tag = InActivityTimer.Started;
            MessageBox.Show("starting");
            IdleTimer.Start();
        }

        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)
        {
            try
            {
                MessageBox.Show("Stopped");
                IdleTimer.Stop();   // not really necessary
                f.MonitorDirectory();
                f.UpdateInActivityStatus();
                IdleTimer.Tick -= TimeDone;
                Application.Idle -= new EventHandler(Application_Idle);
            }
            catch(Exception ex)
            {
                MessageBox.Show(ex.InnerException + ex.Data.ToString());
            }
        }

这是我的GeneStudyForm

public partial class GeneStudyForm
{
GeneStudySystemTimeOutIO GeneStudyIO;
        Func<int> StartTimer;
//Passing the StartInActivityMonitor Method as Func Delegate
public GeneStudyForm(bool isStandalone, string TimeOutFolder, string TimeOutFile, System.Func<int> MyMethod)
{
GeneStudyIO = GeneStudySystemTimeOutIO.GetInstance(TimeOutFolder, TimeOutFile);
            UpdateActivityStatus(AppName.GeneStudyStatus, ActivityStatus.Active);
            this.StartTimer = MyMethod;
}

public void UpdateActivityStatus(AppName name, ActivityStatus status)
        {
            if (GeneStudyIO != null)
            {
                GeneStudyIO.WriteToFile(name, status);
            }
        }
        public void MonitorDirectory()
        {
            FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(GeneStudyIO.GetDriectory());
            fileSystemWatcher.NotifyFilter = NotifyFilters.LastWrite;
            fileSystemWatcher.Filter = "*.json";
            fileSystemWatcher.Changed += FileSystemWatcher_Changed;
            fileSystemWatcher.EnableRaisingEvents = true;
        }

        public void UnRegister(FileSystemWatcher fileSystemWatcher)
        {
            fileSystemWatcher.Changed -= FileSystemWatcher_Changed;
        }
// I am writing the inactive status to a file. So this event will fill
        private void FileSystemWatcher_Changed(object sender, FileSystemEventArgs e)
        {
            try
            {
                var root = GeneStudyIO.GetDesrializedJson();
                if (root != null && root.AllApplications != null)
                {
                    var item = root.AllApplications.Any(x => x.Status == ActivityStatus.Active.ToString());
                    if (!item)
                    {
                        if (InActivecount == 0)
                        {
                            GeneStudyAndApplicationCommon.TimeStatus = InActivityTimer.Ended;
                            MessageBox.Show("I am hiding");
                            this.Hide();
                            InActivecount++;
                        }
                    }
                    else
                    {
                        if (GeneStudyAndApplicationCommon.TimeStatus == InActivityTimer.Ended)
                        {
                            MessageBox.Show("I am showing");
                            this.Show();
                            UnRegister(sender as FileSystemWatcher);
                            UpdateActivityStatus(AppName.GeneStudyStatus, ActivityStatus.Active);
                            MessageBox.Show("Updated Status");
                            if (StartTimer != null)
                            {
                                MessageBox.Show("Starting Timer again");
                                if (StartTimer() == -1)
                                {
                                    MessageBox.Show("Couldn't start timer");
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                SystemDebugLogLogger.LogException(ex);
            }
        }
}

1 个答案:

答案 0 :(得分:0)

这个问题与我发布的完全不同。但我可以解决我的问题。但我想发布它,如果它可以帮助某人。以下是我关注Last User Input

的帖子

我创建了一个名为IdleCheck的类,我在其中获取LastUserInput,如下所示

public static class IdleCheck
    {
        [StructLayout(LayoutKind.Sequential)]
        private struct LASTINPUTINFO
        {

            [MarshalAs(UnmanagedType.U4)]

            public int cbSize;

            [MarshalAs(UnmanagedType.U4)]

            public int dwTime;

        }

        [DllImport("user32.dll")]
        private static extern bool GetLastInputInfo(ref LASTINPUTINFO x);
        public static int GetLastInputTime()
        {
            var inf = new LASTINPUTINFO();
            inf.cbSize = Marshal.SizeOf(inf);
            inf.dwTime = 0;

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

接下来在实际表格中这是我的代码。我正在使用一个简单的是否消息框来查看计时器是否可以停止并在需要时再次调用。您可以应用自己的锁定机制。 我希望应用程序超时,如果它是InActive 20秒。根据需要进行更改。

public partial class Form1 : Form
    {
        Timer timer;
        const int TIMEOUT_DONE = 20000;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            Reset();
        }

        void timer_Tick(object sender, EventArgs e)
        {
            //var ms = TIMEOUT_DONE - IdleCheck.GetLastInputTime();
            if (IdleCheck.GetLastInputTime() > TIMEOUT_DONE)
            {
                DialogResult dialogResult = MessageBox.Show("Sure", "Some Title", MessageBoxButtons.YesNo);
                if (dialogResult == DialogResult.Yes)
                {
                    Stop();
                    Reset();
                }

            }

        }

        public void Reset()
        {
            timer = new Timer();

            timer.Interval = 10000;

            timer.Tick += timer_Tick;

            timer.Start();
        }

        public void Stop()
        {
            timer.Tick -= timer_Tick;
            timer.Stop();
        }

    }