Represents an application and its associated process.
Inheritance: IDisposable
 public void ApplicationProcessFailConfigPathInvalid()
 {
     using (ApplicationProcess process = new ApplicationProcess(Logger, @"C:\Path"))
     {
         process.ConfigPath = @"C:\Path\Invalid>";
     }
 }
 public void ApplicationProcessFailFrameworkVersionInvalid()
 {
     using (ApplicationProcess process = new ApplicationProcess(Logger, @"C:\Path"))
     {
         process.FrameworkVersion = "1.0";
     }
 }
        /// <summary>
        /// Raises an application's Exited event.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event arguments.</param>
        private void ApplicationExited(object sender, EventArgs e)
        {
            ApplicationProcess application = (ApplicationProcess)sender;

            this.logger.Info("Application at '{0}' has exited and will be re-started.", application.Path);
            this.StartApplication(sender);
        }
 public void ApplicationProcessBasePath()
 {
     using (ApplicationProcess process = new ApplicationProcess(Logger, @"C:\Path"))
     {
         Assert.AreEqual(Path.GetFullPath(Path.GetDirectoryName(GetType().Assembly.Location)), process.BasePath);
     }
 }
        /// <summary>
        /// Starts an application.
        /// </summary>
        /// <param name="context">The application to start.</param>
        private void StartApplication(object context)
        {
            ApplicationProcess application = (ApplicationProcess)context;
            bool retry = true;

            while (retry)
            {
                lock (this.locker)
                {
                    if (this.IsRunning && this.applications.IndexOf(application) >= 0 && !application.IsRunning)
                    {
                        retry = !application.Start();
                    }
                    else
                    {
                        retry = false;
                    }
                }
            }
        }
        /// <summary>
        /// Sets the given application's configurable properties from the given configuration element.
        /// </summary>
        /// <param name="application">The application to initialize.</param>
        /// <param name="element">The configuration element to initialize the application from.</param>
        /// <returns>True if the application was initialized successfully, false otherwise.</returns>
        private bool SetApplicationProperties(ApplicationProcess application, ApplicationElement element)
        {
            bool success = true;

            application.Force32Bit = element.Force32Bit;

            try
            {
                application.ConfigPath = element.ApplicationConfigPath;
            }
            catch (ArgumentException ex)
            {
                success = false;
                this.logger.Error(
                    new ConfigurationErrorsException(
                        "The value for 'configPath' contains invalid characters.",
                        ex,
                        element.ElementInformation.Source,
                        element.ElementInformation.LineNumber));
            }

            try
            {
                application.FrameworkVersion = element.Framework;
            }
            catch (ArgumentException ex)
            {
                success = false;
                this.logger.Error(
                    new ConfigurationErrorsException(
                        "The value for 'framework' must be one of: '3.5', '4.0'.",
                        ex,
                        element.ElementInformation.Source,
                        element.ElementInformation.LineNumber));
            }

            return(success);
        }
 public void ApplicationProcessFailThresholdInvalid()
 {
     using (ApplicationProcess process = new ApplicationProcess(Logger, @"C:\Path"))
     {
         process.Threshold = 0;
     }
 }
 public void ApplicationProcessFailPathInvalid()
 {
     using (ApplicationProcess process = new ApplicationProcess(Logger, @"C:\Invalid\Path>"))
     {
     }
 }
 public void ApplicationProcessFailPathEmpty()
 {
     using (ApplicationProcess process = new ApplicationProcess(Logger, null))
     {
     }
 }
        public void ApplicationProcessStopForce()
        {
            string path = ApplicationUtils.CreateValidExampleApplication();
            ManualResetEvent handle = new ManualResetEvent(false);

            try
            {
                using (ApplicationProcess process = new ApplicationProcess(Logger, path, Path.GetFullPath("Collar.exe")))
                {
                    process.Exited += (object sender, EventArgs e) =>
                    {
                        Assert.Fail();
                        handle.Set();
                    };

                    process.KillTimeout += (object sender, EventArgs e) =>
                    {
                        Assert.Fail();
                        handle.Set();
                    };

                    Assert.IsTrue(process.Start());
                    process.Stop(true);
                    WaitHandle.WaitAll(new WaitHandle[] { handle }, 11000);
                }
            }
            finally
            {
                handle.Close();
            }
        }
        public void ApplicationProcessStart()
        {
            string path = ApplicationUtils.CreateValidExampleApplication();

            using (ApplicationProcess process = new ApplicationProcess(Logger, path, Path.GetFullPath("Collar.exe")))
            {
                Assert.IsTrue(process.Start());
            }
        }
        private void CreateRefreshAndPruneApplications(IEnumerable <ApplicationElement> elements)
        {
            List <ApplicationProcess> pruning = this.applications
                                                .Where(a => !elements.Any(e => a.Path.Equals(e.ApplicationPath, StringComparison.OrdinalIgnoreCase)))
                                                .ToList();

            List <ApplicationProcess> existing = this.applications
                                                 .Where(a => elements.Any(e => a.Path.Equals(e.ApplicationPath, StringComparison.OrdinalIgnoreCase)))
                                                 .ToList();

            List <ApplicationElement> creating = elements
                                                 .Where(e => !this.applications.Any(a => e.ApplicationPath.Equals(a.Path, StringComparison.OrdinalIgnoreCase)))
                                                 .ToList();

            // Prune removed applications.
            foreach (ApplicationProcess application in pruning)
            {
                application.Exited -= new EventHandler(this.ApplicationExited);
                application.Stop(true);
                application.Dispose();
            }

            // Stop and re-initialize changed applications.
            foreach (ApplicationProcess application in existing)
            {
                ApplicationElement element = elements.Where(e => application.Path.Equals(e.ApplicationPath, StringComparison.OrdinalIgnoreCase)).First();

                if (!(application.ConfigPath ?? string.Empty).Equals(element.ApplicationConfigPath, StringComparison.OrdinalIgnoreCase) ||
                    application.Force32Bit != element.Force32Bit ||
                    application.FrameworkVersion != element.Framework)
                {
                    if (this.SetApplicationProperties(application, element))
                    {
                        application.Stop(true);
                    }
                }
            }

            // Create added applications.
            foreach (ApplicationElement element in creating)
            {
                ApplicationProcess application = null;

                try
                {
                    try
                    {
                        application = new ApplicationProcess(this.logger, element.ApplicationPath, this.exePath);
                    }
                    catch (ArgumentException ex)
                    {
                        this.logger.Error(
                            new ConfigurationErrorsException(
                                "The value for 'path' contains invalid characters.",
                                ex,
                                element.ElementInformation.Source,
                                element.ElementInformation.LineNumber));
                    }

                    if (application != null)
                    {
                        application.Exited += new EventHandler(this.ApplicationExited);

                        if (this.SetApplicationProperties(application, element))
                        {
                            existing.Add(application);
                        }
                    }
                }
                catch
                {
                    if (application != null)
                    {
                        application.Dispose();
                    }

                    throw;
                }
            }

            lock (this.locker)
            {
                this.applications = existing;
            }
        }
        /// <summary>
        /// Sets the given application's configurable properties from the given configuration element.
        /// </summary>
        /// <param name="application">The application to initialize.</param>
        /// <param name="element">The configuration element to initialize the application from.</param>
        /// <returns>True if the application was initialized successfully, false otherwise.</returns>
        private bool SetApplicationProperties(ApplicationProcess application, ApplicationElement element)
        {
            bool success = true;
            application.Force32Bit = element.Force32Bit;

            try
            {
                application.ConfigPath = element.ApplicationConfigPath;
            }
            catch (ArgumentException ex)
            {
                success = false;
                this.logger.Error(
                    new ConfigurationErrorsException(
                        "The value for 'configPath' contains invalid characters.",
                        ex,
                        element.ElementInformation.Source,
                        element.ElementInformation.LineNumber));
            }

            try
            {
                application.FrameworkVersion = element.Framework;
            }
            catch (ArgumentException ex)
            {
                success = false;
                this.logger.Error(
                    new ConfigurationErrorsException(
                        "The value for 'framework' must be one of: '3.5', '4.0'.",
                        ex,
                        element.ElementInformation.Source,
                        element.ElementInformation.LineNumber));
            }

            return success;
        }
        private void CreateRefreshAndPruneApplications(IEnumerable<ApplicationElement> elements)
        {
            List<ApplicationProcess> pruning = this.applications
                .Where(a => !elements.Any(e => a.Path.Equals(e.ApplicationPath, StringComparison.OrdinalIgnoreCase)))
                .ToList();

            List<ApplicationProcess> existing = this.applications
                .Where(a => elements.Any(e => a.Path.Equals(e.ApplicationPath, StringComparison.OrdinalIgnoreCase)))
                .ToList();

            List<ApplicationElement> creating = elements
                .Where(e => !this.applications.Any(a => e.ApplicationPath.Equals(a.Path, StringComparison.OrdinalIgnoreCase)))
                .ToList();

            // Prune removed applications.
            foreach (ApplicationProcess application in pruning)
            {
                application.Exited -= new EventHandler(this.ApplicationExited);
                application.Stop(true);
                application.Dispose();
            }

            // Stop and re-initialize changed applications.
            foreach (ApplicationProcess application in existing)
            {
                ApplicationElement element = elements.Where(e => application.Path.Equals(e.ApplicationPath, StringComparison.OrdinalIgnoreCase)).First();

                if (!(application.ConfigPath ?? string.Empty).Equals(element.ApplicationConfigPath, StringComparison.OrdinalIgnoreCase)
                    || application.Force32Bit != element.Force32Bit
                    || application.FrameworkVersion != element.Framework)
                {
                    if (this.SetApplicationProperties(application, element))
                    {
                        application.Stop(true);
                    }
                }
            }

            // Create added applications.
            foreach (ApplicationElement element in creating)
            {
                ApplicationProcess application = null;

                try
                {
                    try
                    {
                        application = new ApplicationProcess(this.logger, element.ApplicationPath, this.exePath);
                    }
                    catch (ArgumentException ex)
                    {
                        this.logger.Error(
                            new ConfigurationErrorsException(
                                "The value for 'path' contains invalid characters.",
                                ex,
                                element.ElementInformation.Source,
                                element.ElementInformation.LineNumber));
                    }

                    if (application != null)
                    {
                        application.Exited += new EventHandler(this.ApplicationExited);

                        if (this.SetApplicationProperties(application, element))
                        {
                            existing.Add(application);
                        }
                    }
                }
                catch
                {
                    if (application != null)
                    {
                        application.Dispose();
                    }

                    throw;
                }
            }

            lock (this.locker)
            {
                this.applications = existing;
            }
        }