public void GracePeriod()
        {
            var grace_timespan      = TimeSpan.FromSeconds(5);
            var grace_timespan_half = TimeSpan.FromSeconds(grace_timespan.TotalSeconds / 2);

            ProcessOptions options = ResponsiveWindowedProcessOptions;

            options.CrashedIfNotRunning   = true;
            options.GracePeriodEnabled    = true;
            options.GracePeriodDuration   = (uint)grace_timespan.TotalSeconds;
            options.InitialStateEnumValue = ProcessRunner.Status.Running;

            using (ProcessRunner runner = new ProcessRunner(options))
            {
                runner.Monitor();
                Assert.IsNotNull(runner.Process);

                ProcessHelper.Shutdown(runner.Process.Id);
                Thread.Sleep(EpsilonTime);
                runner.Monitor();
                Assert.IsNull(runner.Process);

                Thread.Sleep(grace_timespan_half);
                runner.Monitor();
                Assert.IsNull(runner.Process);

                Thread.Sleep(grace_timespan_half + EpsilonTime);
                runner.Monitor();
                Assert.IsNotNull(runner.Process);
            }
        }
        public void DoubleCheckPeriod()
        {
            var check_timespan      = TimeSpan.FromSeconds(2);
            var check_timespan_half = TimeSpan.FromSeconds(check_timespan.TotalSeconds / 2);

            ProcessOptions options = UnresponsiveWindowedProcessOptions;

            options.CrashedIfNotRunning   = true;
            options.CrashedIfUnresponsive = true;
            options.DoubleCheckEnabled    = true;
            options.DoubleCheckDuration   = (uint)check_timespan.TotalSeconds;
            options.InitialStateEnumValue = ProcessRunner.Status.Running;

            using (ProcessRunner runner = new ProcessRunner(options))
            {
                runner.Monitor();
                Assert.IsNotNull(runner.Process);
                runner.WaitUntilUnresponsive();

                Thread.Sleep(EpsilonTime);
                runner.Monitor();

                Thread.Sleep(check_timespan_half);
                runner.Monitor();
                Assert.IsNotNull(runner.Process);

                Thread.Sleep(check_timespan_half + EpsilonTime);
                runner.Monitor();
                Assert.IsNull(runner.Process);
            }

            options.CommandLine = string.Format("{0} {1}",
                                                options.CommandLine,
                                                (int)check_timespan_half.TotalSeconds);

            using (ProcessRunner runner = new ProcessRunner(options))
            {
                runner.Start();

                Thread.Sleep(check_timespan_half);
                runner.Monitor();
                Assert.IsNotNull(runner.Process);

                Thread.Sleep(check_timespan + EpsilonTime);
                runner.Monitor();
                Assert.IsNotNull(runner.Process);
            }
        }
        public void BringToFront()
        {
            ProcessOptions options = ResponsiveWindowedProcessOptions;

            using (ProcessRunner runner1 = new ProcessRunner(options))
                using (ProcessRunner runner2 = new ProcessRunner(options))
                {
                    runner1.Start();
                    runner2.Start();

                    runner1.Monitor();
                    runner2.Monitor();

                    bool passed = false;
                    uint passes = 10;

                    for (uint i = 0; i < passes && !passed; ++i)
                    {
                        runner1.BringToFront(true);
                        passed |= (ProcessHelper.GetForegroundWindow() == runner1.Process.MainWindowHandle);
                    }

                    Assert.IsTrue(passed);

                    passed = false;

                    for (uint i = 0; i < passes && !passed; ++i)
                    {
                        runner2.BringToFront(true);
                        passed |= (ProcessHelper.GetForegroundWindow() == runner2.Process.MainWindowHandle);
                    }

                    Assert.IsTrue(passed);
                }
        }
        public void UnresponsiveProcess()
        {
            ProcessOptions options = UnresponsiveWindowedProcessOptions;

            options.CrashedIfNotRunning   = true;
            options.CrashedIfUnresponsive = true;
            options.InitialStateEnumValue = ProcessRunner.Status.Running;

            using (ProcessRunner runner = new ProcessRunner(options))
            {
                runner.Stop();
                Assert.IsNull(runner.Process);
            }

            using (ProcessRunner runner = new ProcessRunner(options))
            {
                runner.Start();
                runner.WaitUntilUnresponsive();

                runner.Monitor();
                Assert.IsNull(runner.Process);
            }

            options.CrashedIfUnresponsive = false;
            using (ProcessRunner runner = new ProcessRunner(options))
            {
                runner.Start();

                runner.Monitor();
                Assert.IsNotNull(runner.Process);

                runner.Stop();
                Assert.IsNull(runner.Process);
            }
        }
        public void StartupStateAssumeCrashIfNotRunning()
        {
            ProcessOptions options = ResponsiveWindowedProcessOptions;

            options.CrashedIfNotRunning = true;

            options.InitialStateEnumValue = ProcessRunner.Status.Invalid;
            using (ProcessRunner runner = new ProcessRunner(options))
            {
                Assert.AreEqual(runner.State, ProcessRunner.Status.Stopped);
                Assert.IsNull(runner.Process);

                runner.Monitor();
                Assert.IsNull(runner.Process);
            }

            options.InitialStateEnumValue = ProcessRunner.Status.Disabled;
            using (ProcessRunner runner = new ProcessRunner(options))
            {
                Assert.AreEqual(runner.State, ProcessRunner.Status.Disabled);
                Assert.IsNull(runner.Process);

                runner.Monitor();
                Assert.IsNull(runner.Process);
            }

            options.InitialStateEnumValue = ProcessRunner.Status.Stopped;
            using (ProcessRunner runner = new ProcessRunner(options))
            {
                Assert.AreEqual(runner.State, ProcessRunner.Status.Stopped);
                Assert.IsNull(runner.Process);

                runner.Monitor();
                Assert.IsNull(runner.Process);
            }

            options.InitialStateEnumValue = ProcessRunner.Status.Running;
            using (ProcessRunner runner = new ProcessRunner(options))
            {
                Assert.AreEqual(runner.State, ProcessRunner.Status.Running);
                Assert.IsNull(runner.Process);

                runner.Monitor();
                Assert.IsNotNull(runner.Process);
            }
        }
        public void StopCallback()
        {
            ProcessOptions options = ResponsiveWindowedProcessOptions;

            options.CrashedIfNotRunning   = false;
            options.InitialStateEnumValue = ProcessRunner.Status.Stopped;

            using (ProcessRunner runner = new ProcessRunner(options))
            {
                runner.Start();
                ProcessHelper.Shutdown(runner.Process.Id);

                Thread.Sleep(EpsilonTime);
                Assert.IsNotNull(runner.Process);

                runner.Monitor();
                Assert.IsNotNull(runner.Process);
            }
        }
        public void StateChangesDoNotAssumeCrashIfNotRunning()
        {
            ProcessOptions options = ResponsiveWindowedProcessOptions;

            options.CrashedIfNotRunning = false;

            // running to stopped
            options.InitialStateEnumValue = ProcessRunner.Status.Running;
            using (ProcessRunner runner = new ProcessRunner(options))
            {
                runner.Monitor();
                Assert.IsNotNull(runner.Process);
                Assert.AreEqual(runner.State, ProcessRunner.Status.Running);

                runner.State = ProcessRunner.Status.Stopped;
                runner.Monitor();
                Assert.IsNull(runner.Process);
                Assert.AreEqual(runner.State, ProcessRunner.Status.Stopped);
            }

            // running to disabled
            options.InitialStateEnumValue = ProcessRunner.Status.Running;
            using (ProcessRunner runner = new ProcessRunner(options))
            {
                runner.Monitor();
                Assert.IsNotNull(runner.Process);
                Assert.AreEqual(runner.State, ProcessRunner.Status.Running);

                runner.State = ProcessRunner.Status.Disabled;
                runner.Monitor();
                Assert.IsNull(runner.Process);
                Assert.AreEqual(runner.State, ProcessRunner.Status.Disabled);
            }

            // stopped to running
            options.InitialStateEnumValue = ProcessRunner.Status.Stopped;
            using (ProcessRunner runner = new ProcessRunner(options))
            {
                runner.Monitor();
                Assert.IsNull(runner.Process);
                Assert.AreEqual(runner.State, ProcessRunner.Status.Stopped);

                runner.State = ProcessRunner.Status.Running;
                runner.Monitor();
                Assert.IsNotNull(runner.Process);
                Assert.AreEqual(runner.State, ProcessRunner.Status.Running);
            }

            // stopped to disabled
            options.InitialStateEnumValue = ProcessRunner.Status.Stopped;
            using (ProcessRunner runner = new ProcessRunner(options))
            {
                runner.Monitor();
                Assert.IsNull(runner.Process);
                Assert.AreEqual(runner.State, ProcessRunner.Status.Stopped);

                runner.State = ProcessRunner.Status.Disabled;
                runner.Monitor();
                Assert.IsNull(runner.Process);
                Assert.AreEqual(runner.State, ProcessRunner.Status.Disabled);
            }

            // disabled to running
            options.InitialStateEnumValue = ProcessRunner.Status.Disabled;
            using (ProcessRunner runner = new ProcessRunner(options))
            {
                runner.Monitor();
                Assert.IsNull(runner.Process);
                Assert.AreEqual(runner.State, ProcessRunner.Status.Disabled);

                runner.State = ProcessRunner.Status.Running;
                runner.Monitor();
                Assert.IsNotNull(runner.Process);
                Assert.AreEqual(runner.State, ProcessRunner.Status.Running);
            }

            // disabled to stopped
            options.InitialStateEnumValue = ProcessRunner.Status.Disabled;
            using (ProcessRunner runner = new ProcessRunner(options))
            {
                runner.Monitor();
                Assert.IsNull(runner.Process);
                Assert.AreEqual(runner.State, ProcessRunner.Status.Disabled);

                runner.State = ProcessRunner.Status.Stopped;
                runner.Monitor();
                Assert.IsNull(runner.Process);
                Assert.AreEqual(runner.State, ProcessRunner.Status.Stopped);
            }
        }