protected override void OnStop()
 {
     if (this.mainThread.IsAlive)
     {
         this.mainThread.Abort();
     }
     this.mainThread.Join();
     ServiceLog.WriteApplicationStop();
 }
 private void DeleteRegistryKeyValue(string key, string valueName)
 {
     try
     {
         RegistryUtils.DeleteRegistryKeyValue(key, valueName);
     }
     catch (Exception ex)
     {
         ServiceLog.WriteError("Registry error:", ex);
     }
 }
        private void DelayOnStart()
        {
            int startupDelay = 0;

            if (Int32.TryParse(ConfigurationManager.AppSettings["Service.StartupDelay"], out startupDelay) &&
                startupDelay > 0)
            {
                ServiceLog.WriteStart("Delay on service start-up");
                System.Threading.Thread.Sleep(startupDelay);
                ServiceLog.WriteEnd("Delay on service start-up");
            }
        }
        private void Start()
        {
            //log
            ServiceLog.WriteApplicationStart();

            // delay (for sync with KVP exchange service)
            DelayOnStart();

            //init
            InitializeProvisioningModules();
            InitializeTimers();

            // start timer
            StartSummaryTimer();

            //run tasks
            ProcessTasks();
        }
 private void RebootSystem()
 {
     try
     {
         ServiceLog.WriteStart("RebootSystem");
         WmiUtils wmi = new WmiUtils("root\\cimv2");
         ManagementObjectCollection objOses = wmi.ExecuteQuery("SELECT * FROM Win32_OperatingSystem");
         foreach (ManagementObject objOs in objOses)
         {
             objOs.Scope.Options.EnablePrivileges = true;
             objOs.InvokeMethod("Reboot", null);
         }
         ServiceLog.WriteEnd("RebootSystem");
     }
     catch (Exception ex)
     {
         ServiceLog.WriteError("Reboot System error:", ex);
     }
 }
        private void InitializeTimers()
        {
            // idle timer
            idleTimer           = new Timer();
            idleTimer.AutoReset = false;
            double idleInterval;

            if (!Double.TryParse(ConfigurationManager.AppSettings["Service.ExitIdleInterval"], out idleInterval))
            {
                ServiceLog.WriteError("Invalid configuration parameter: Service.ExitIdleInterval");
                idleInterval = 600000;
            }
            idleTimer.Interval = idleInterval;
            idleTimer.Enabled  = false;
            idleTimer.Elapsed += new ElapsedEventHandler(OnIdleTimerElapsed);

            // poll timer
            pollTimer           = new Timer();
            pollTimer.AutoReset = false;
            double pollInterval;

            if (!Double.TryParse(ConfigurationManager.AppSettings["Service.RegistryPollInterval"], out pollInterval))
            {
                ServiceLog.WriteError("Invalid configuration parameter: Service.RegistryPollInterval");
                pollInterval = 60000;
            }
            pollTimer.Interval = pollInterval;
            pollTimer.Enabled  = false;
            pollTimer.Elapsed += new ElapsedEventHandler(OnPollTimerElapsed);

            // system symmary timer
            summaryTimer = new Timer();
            double summaryInterval;

            if (!Double.TryParse(ConfigurationManager.AppSettings["Service.SystemSummaryInterval"], out summaryInterval))
            {
                ServiceLog.WriteError("Invalid configuration parameter: Service.SystemSummaryInterval");
                summaryInterval = 15000;
            }
            summaryTimer.Interval = summaryInterval;
            summaryTimer.Enabled  = false;
            summaryTimer.Elapsed += new ElapsedEventHandler(OnSummaryTimerElapsed);
        }
        private void InitializeProvisioningModules()
        {
            ServiceLog.WriteStart("Loading provisioning modules...");
            provisioningModules = new Dictionary <string, string>();

            Configuration         config  = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            ModuleSettingsSection section = config.Sections["moduleSettings"] as ModuleSettingsSection;

            if (section != null)
            {
                foreach (string key in section.Modules.AllKeys)
                {
                    provisioningModules.Add(key, section.Modules[key].Value);
                }
            }
            else
            {
                ServiceLog.WriteError("Modules configuration section not found");
            }
            ServiceLog.WriteEnd(string.Format("{0} module(s) loaded", provisioningModules.Count));
        }
        private void DeleteOldResults()
        {
            // get the list of input tasks
            string[]      strTasks = RegistryUtils.GetRegistryKeyValueNames(RegistryInputKey);
            List <string> tasks    = new List <string>();

            foreach (string strTask in strTasks)
            {
                if (!string.IsNullOrEmpty(strTask) && strTask.StartsWith(TaskPrefix) && strTask != CurrentTaskName)
                {
                    //save only WebsitePanel tasks
                    tasks.Add(strTask);
                }
            }

            // get the list of task results
            int deletedResults = 0;

            string[] strResults = RegistryUtils.GetRegistryKeyValueNames(RegistryOutputKey);
            foreach (string strResult in strResults)
            {
                if (!string.IsNullOrEmpty(strResult) && strResult.StartsWith(TaskPrefix) && strResult != CurrentTaskName)
                {
                    // check if task result exists in the input tasks
                    if (!tasks.Contains(strResult))
                    {
                        DeleteRegistryKeyValue(RegistryOutputKey, strResult);
                        ServiceLog.WriteInfo(string.Format("Deleted activity result: {0}", strResult));
                        deletedResults++;
                    }
                }
            }

            if (deletedResults > 0)
            {
                ServiceLog.WriteEnd(string.Format("{0} result(s) deleted", deletedResults));
            }
        }
        private void ProcessTasks()
        {
            // delete old results
            DeleteOldResults();

            //process all tasks
            while (true)
            {
                //load completed tasks results
                string[]      strResults = RegistryUtils.GetRegistryKeyValueNames(RegistryOutputKey);
                List <string> results    = new List <string>();
                foreach (string strResult in strResults)
                {
                    if (!string.IsNullOrEmpty(strResult) && strResult.StartsWith(TaskPrefix) && strResult != CurrentTaskName)
                    {
                        //save only WebsitePanel tasks
                        results.Add(strResult);
                    }
                }

                // sorted list of tasks - will be sorted by the TaskID (time in ticks)
                SortedList <long, string> tasks = new SortedList <long, string>();

                //load task definitions from input registry key
                string[] strTasks = RegistryUtils.GetRegistryKeyValueNames(RegistryInputKey);
                foreach (string strTask in strTasks)
                {
                    if (results.Contains(strTask))
                    {
                        continue; // skip completed tasks
                    }
                    if (!string.IsNullOrEmpty(strTask) && strTask.StartsWith(TaskPrefix))
                    {
                        // extract Task ID parameter
                        int idx = strTask.LastIndexOf('-');
                        if (idx == -1)
                        {
                            continue;
                        }

                        string strTaskId = strTask.Substring(idx + 1);
                        long   taskId    = 0;
                        try
                        {
                            taskId = Int64.Parse(strTaskId);
                        }
                        catch
                        {
                            continue; // wrong task format
                        }

                        //save only WebsitePanel tasks
                        if (!tasks.ContainsKey(taskId))
                        {
                            tasks.Add(taskId, strTask);
                        }
                    }
                }
                if (tasks.Count == 0)
                {
                    if (rebootRequired)
                    {
                        ServiceLog.WriteInfo("Reboot required");
                        RebootSystem();
                        return;
                    }

                    //start timers
                    StartPollTimer();                     //starts task processing after poll interval
                    StartIdleTimer();                     //stops service if idle
                    //no tasks - exit!
                    return;
                }
                else
                {
                    //stop idle timer as we need to process tasks
                    StopIdleTimer();
                }

                ExecutionContext context = null;
                foreach (long tid in tasks.Keys)
                {
                    //find first correct task
                    string taskDefinition = tasks[tid];
                    string taskParameters = RegistryUtils.GetRegistryKeyStringValue(RegistryInputKey, taskDefinition);
                    if (taskDefinition.LastIndexOf("-") == -1 || taskDefinition.LastIndexOf('-') == taskDefinition.Length - 1)
                    {
                        ServiceLog.WriteError(string.Format("Task was deleted from queue as its definition is invalid : {0}", taskDefinition));
                        DeleteRegistryKeyValue(RegistryInputKey, taskDefinition);
                        //go to next task
                        continue;
                    }
                    string taskName = taskDefinition.Substring(0, taskDefinition.LastIndexOf("-")).Substring(TaskPrefix.Length);
                    string taskId   = taskDefinition.Substring(taskDefinition.LastIndexOf('-') + 1);

                    if (!provisioningModules.ContainsKey(taskName))
                    {
                        ServiceLog.WriteError(string.Format("Task was deleted from queue as its definition was not found : {0}", taskName));
                        DeleteRegistryKeyValue(RegistryInputKey, taskDefinition);
                        //go to next task
                        continue;
                    }
                    //prepare execution context for correct task
                    context              = new ExecutionContext();
                    context.ActivityID   = taskId;
                    context.ActivityName = taskName;
                    ParseParameters(context.Parameters, taskParameters);
                    context.ActivityDefinition = taskDefinition;
                    break;
                }
                if (context != null)
                {
                    string          type  = provisioningModules[context.ActivityName];
                    ExecutionResult res   = null;
                    DateTime        start = DateTime.Now;

                    try
                    {
                        //load module and run task
                        ServiceLog.WriteStart(string.Format("Starting '{0}' module...", context.ActivityName));
                        context.Progress = 0;
                        res = ModuleLoader.Run(type, ref context);
                        context.Progress = 100;
                        ServiceLog.WriteEnd(string.Format("'{0}' module finished.", context.ActivityName));
                    }
                    catch (Exception ex)
                    {
                        ServiceLog.WriteError("Unhandled exception:", ex);
                        res              = new ExecutionResult();
                        res.ResultCode   = -1;
                        res.ErrorMessage = string.Format("Unhandled exception : {0}", ex);
                    }
                    DateTime end = DateTime.Now;
                    SaveExecutionResult(context.ActivityDefinition, res, start, end);
                    //DeleteRegistryKeyValue(RegistryInputKey, context.ActivityDefinition);

                    if (res.RebootRequired)
                    {
                        rebootRequired = true;
                    }
                }
            }
        }
 static void OnDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
 {
     ServiceLog.WriteError("Remote application domain error", (Exception)e.ExceptionObject);
 }