Beispiel #1
0
        /// <summary>
        /// Unloads a module.
        /// </summary>
        /// <param name="moduleData">The module.</param>
        private static void StopModule(ModuleData moduleData)
        {
            try
            {
                for (int i = moduleData.Tasks.Length - 1; i >= 0; i--)
                {
                    TaskManagerService.Logger.Log(string.Format("Stopping task '{0}'...", moduleData.Tasks[i].TaskName));
                    TaskSupervisor.RemoveTask(moduleData.Tasks[i]);
                }

                TaskManagerService.Logger.Log(string.Format("Unloading AppDomain '{0}'...", moduleData.Domain.FriendlyName));
                AppDomain.Unload(moduleData.Domain);

                TaskManagerService.Logger.Log("AppDomain successfully unloaded.");

                if (moduleData.ZipFile != null && moduleData.ZipDirectory != null)
                {
                    Directory.Delete(moduleData.ZipDirectory, true);
                }

                _moduleList.Remove(moduleData);
            }
            catch (Exception e)
            {
                TaskManagerService.Logger.Log(string.Format("Exception caught while shutting down module '{0}'", moduleData.DllFile), e);
                throw;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Called when the service is being started by the SCM.
        /// </summary>
        /// <param name="args">The arguments.</param>
        protected override void OnStart(string[] args)
        {
////#if DEBUG
////            System.Threading.Thread.Sleep(10000);
////#endif

            LogInfo("Starting service...");
            try
            {
                var options = TaskManagerOptions.Create("Start parameters: ", args);
                Initialize(options.EventLog);
                TaskSupervisor.Initialize(options.StatsStrategy);
                ModuleSupervisor.Initialize();

                LogInfo("Service successfully started...");

                ModuleSupervisor.Execute();
            }
            catch (Exception e)
            {
                LogError("Unable to start service.", e);

                File.WriteAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TaskManager.start.error.txt"), e.Message);
                throw;
            }
        }
Beispiel #3
0
        /// <summary>
        /// Loads a module.
        /// </summary>
        /// <param name="dllFile">The path to the module DLL file.</param>
        /// <param name="xmlFile">The path to the module XML configuration file.</param>
        /// <param name="startImmediately">True if execution should be started immediately after configuring the module, false if module should be configured but not started.</param>
        private static void LoadAndConfigure(string dllFile, string xmlFile, bool startImmediately)
        {
            string modulePath = Path.GetDirectoryName(dllFile);

            if (!modulePath.EndsWith(Path.DirectorySeparatorChar.ToString()))
            {
                modulePath += Path.DirectorySeparatorChar;
            }

            string[] files = Directory.GetFiles(modulePath, "*.*", SearchOption.AllDirectories);

            AppDomainSetup domainSetup = new AppDomainSetup();

            domainSetup.ShadowCopyFiles   = "true";
            domainSetup.ApplicationBase   = modulePath;
            domainSetup.ConfigurationFile = dllFile + ".config";

            AppDomain domain = AppDomain.CreateDomain(dllFile, null, domainSetup);

            TaskManagerService.Logger.Log(string.Format("Module found: '{0}', configuration file: '{1}', scanning assembly for tasks...", dllFile, xmlFile));

            if (modulePath != AppDomain.CurrentDomain.BaseDirectory)
            {
                string loaderDll     = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TaskManager.Loader.dll");
                string tempLoaderDll = Path.Combine(modulePath, "TaskManager.Loader.dll");
                string commonDll     = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TaskManager.Common.dll");
                string tempCommonDll = Path.Combine(modulePath, "TaskManager.Common.dll");

                File.Copy(loaderDll, tempLoaderDll, true);
                File.Copy(commonDll, tempCommonDll, true);
            }

            AssemblyName loaderAssemblyName = AssemblyName.GetAssemblyName(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TaskManager.Loader.dll"));
            Loader       loader             = (Loader)domain.CreateInstanceAndUnwrap(loaderAssemblyName.ToString(), "TaskManager.Loader");

            TaskWrapper[] tasks = loader.LoadAndConfigure(dllFile, xmlFile, TaskManagerService.Logger, AppDomain.CurrentDomain.BaseDirectory);

            ModuleData newModule = new ModuleData();

            newModule.BasePath = Path.GetDirectoryName(dllFile);
            newModule.Tasks    = tasks;
            newModule.DllFile  = dllFile;
            newModule.XmlFile  = xmlFile;
            newModule.Files    = new List <string>(files);
            newModule.Domain   = domain;

            if (startImmediately)
            {
                foreach (TaskWrapper task in newModule.Tasks)
                {
                    TaskSupervisor.ScheduleTask(task);
                }
            }

            _moduleList.Add(newModule);
        }
Beispiel #4
0
        /// <summary>
        /// Runs the task manager from the console.
        /// </summary>
        private static void RunFromConsole()
        {
            Console.WriteLine("Press ENTER to locate task modules.");

            Console.ReadLine();

            TaskManagerService.LogInfo("Initializing service...");
            try
            {
                TaskSupervisor.Initialize();
                ModuleSupervisor.Initialize();
            }
            catch (Exception e)
            {
                TaskManagerService.LogError("Unable to initialize service.", e);
                return;
            }

            Console.WriteLine("Press ENTER to start.");

            Console.ReadLine();

            try
            {
                TaskManagerService.LogInfo("Service successfully started...");

                ModuleSupervisor.Execute();
            }
            catch (Exception e)
            {
                TaskManagerService.LogError("Unable to start service.", e);
                return;
            }

            Console.WriteLine("Press ENTER to stop.");

            // If you are debugging, you can freeze the main thread here.
            Console.ReadLine();

            TaskManagerService.LogInfo("Stopping service...");
            try
            {
                ModuleSupervisor.Shutdown();
                TaskSupervisor.Shutdown();
                TaskManagerService.LogInfo("Service successfully stopped...");
            }
            catch (Exception e)
            {
                TaskManagerService.LogError("Unable to stop service.", e);
                return;
            }

            Console.WriteLine("Press ENTER to finish.");
            Console.ReadLine();
        }
Beispiel #5
0
        /// <summary>
        /// Loads all modules.
        /// </summary>
        public static void Execute()
        {
            if (null == _moduleList)
            {
                throw new Exception("TaskManager failed to initialize.");
            }

            lock (_moduleListLock)
            {
                foreach (ModuleData module in _moduleList)
                {
                    foreach (TaskWrapper task in module.Tasks)
                    {
                        TaskManagerService.Logger.Log(string.Format("Registering task '{0}'...", task.TaskName));
                        TaskSupervisor.ScheduleTask(task);
                    }
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Called when the service is being stopped by the SCM.
        /// </summary>
        protected override void OnStop()
        {
            LogInfo("Stopping service...");
            try
            {
                ModuleSupervisor.Shutdown();
                TaskSupervisor.Shutdown();
                LogInfo("Service successfully stopped...");
            }
            catch (Exception e)
            {
                LogError("Unable to stop service.", e);
                throw;
            }

            lock (_eventLog)
            {
                _eventLog.Close();
                _eventLog = null;
            }
        }
        /// <summary>
        /// Called when the service is being started by the SCM.
        /// </summary>
        /// <param name="args">The arguments.</param>
        protected override void OnStart(string[] args)
        {
            ////#if DEBUG
            ////            System.Threading.Thread.Sleep(10000);
            ////#endif

            LogInfo("Starting service...");
            try
            {
                TaskSupervisor.Initialize();
                ModuleSupervisor.Initialize();
                LogInfo("Service successfully started...");

                ModuleSupervisor.Execute();
            }
            catch (Exception e)
            {
                LogError("Unable to start service.", e);
                throw;
            }
        }
Beispiel #8
0
            /// <summary>
            /// The thread loop.
            /// </summary>
            private void Loop()
            {
                DateTime lastRun = DateTime.Now;

                while (true)
                {
                    lock (TaskSupervisor._taskLock)
                    {
                        this._task = TaskSupervisor.GetScheduledTask(this);
                    }

                    System.Threading.Thread.MemoryBarrier();

                    if (null != this._task)
                    {
                        bool result = false;

                        long runTime = -1;

                        TaskSupervisor.NotifyStart(this._task);

                        this.StartingTime = lastRun = DateTime.Now;
                        this.IsRunning    = true;
                        System.Threading.Thread.MemoryBarrier();

                        Stopwatch timer = Stopwatch.StartNew();

                        try
                        {
                            result = this._task.Execute();

                            runTime = timer.ElapsedTicks;
                        }
                        catch (ThreadAbortException)
                        {
                            this._task = null;
                            throw;
                        }
                        catch (AppDomainUnloadedException)
                        {
                            this._task = null;
                            throw;
                        }
                        catch (Exception ex)
                        {
                            this.IsRunning = false;
                            if (!TaskSupervisor.NotifyException("Exception caught while executing task.", ex))
                            {
                                this._task = null;
                                System.Threading.Thread.MemoryBarrier();
                                throw;
                            }
                        }
                        finally
                        {
                            lastRun           = DateTime.Now;
                            this.IsRunning    = false;
                            this.StartingTime = DateTime.MinValue;
                            System.Threading.Thread.MemoryBarrier();
                            TaskSupervisor.NotifyEnd(this._task, runTime);
                        }

                        lock (TaskSupervisor._taskLock)
                        {
                            try
                            {
                                TaskWrapper toReturn = this._task;
                                this._task = null;
                                TaskSupervisor.RescheduleTask(toReturn, result);
                            }
                            catch (AppDomainUnloadedException)
                            {
                            }

                            this._task = null;
                        }

                        System.Threading.Thread.MemoryBarrier();

                        Thread.Sleep(100);
                    }
                    else
                    {
                        if (lastRun.AddSeconds(IdleTimeout) <= DateTime.Now)
                        {
                            TaskSupervisor.NotifyIdleThread(this);
                        }

                        Thread.Sleep(250);
                    }
                }
            }
Beispiel #9
0
        private static void RunFromConsole(string[] args)
        {
            ShowHeader();
            TaskManagerOptions options;

            try
            {
                options = TaskManagerOptions.Create("TaskManager.exe", args);
            }
            catch (Exception ex)
            {
                Show("Argument parsing error: ");
                Show(ex.Message);
                Show("Try `TaskManager --help` for more information");
                Environment.Exit(3);
                return;
            }

            if (options.ShowHelp)
            {
                Show(options.HelpText);
                return;
            }

            WaitUserInteraction(options, "Press ENTER to locate task modules.");
            TaskManagerService.LogInfo("Initializing service...");

            try
            {
                Show("Event log: {0}", options.EventLog.GetType().Name);
                Show("Stats strategy: {0}", options.StatsStrategy.GetType().Name);

                TaskSupervisor.Initialize(options.StatsStrategy);
                TaskManagerService.Initialize(options.EventLog);
                ModuleSupervisor.Initialize();
            }
            catch (Exception e)
            {
                TaskManagerService.LogError("Unable to initialize service.", e);
                WaitUserInteraction(options);
                return;
            }

            WaitUserInteraction(options, "Press ENTER to start.");

            try
            {
                TaskManagerService.LogInfo("Service successfully started...");
                ModuleSupervisor.Execute();

                if (options.NonStop && options.NonStopWait > 0)
                {
                    Show("Waiting {0} milliseconds to tasks execution...", options.NonStopWait);
                    Thread.Sleep(options.NonStopWait);
                }
            }
            catch (Exception e)
            {
                TaskManagerService.LogError("Unable to start service.", e);
                WaitUserInteraction(options);

                return;
            }

            // If you are debugging, you can freeze the main thread here.
            WaitUserInteraction(options, "Press ENTER to stop.");

            TaskManagerService.LogInfo("Stopping service...");
            try
            {
                ModuleSupervisor.Shutdown();
                TaskSupervisor.Shutdown();
                TaskManagerService.LogInfo("Service successfully stopped...");
            }
            catch (Exception e)
            {
                TaskManagerService.LogError("Unable to stop service.", e);
                return;
            }

            WaitUserInteraction(options, "Press ENTER to finish.");
        }
Beispiel #10
0
        /// <summary>
        /// Loads a module from a zip file.
        /// </summary>
        /// <param name="zipFile">The path to the zip file.</param>
        /// <param name="startImmediately">True if execution should be started immediately after configuring the module, false if module should be configured but not started.</param>
        private static void LoadZipAndConfigure(string zipFile, bool startImmediately)
        {
            string tempPath = null;

            int i = 0;

            while (Directory.Exists(tempPath = Path.Combine(Path.Combine(Path.GetTempPath(), "TaskManager"), Path.GetRandomFileName())))
            {
                i++;
                if (i == 10)
                {
                    throw new Exception("Failed to create a new temporary folder.");
                }
            }

            if (!tempPath.EndsWith(Path.DirectorySeparatorChar.ToString()))
            {
                tempPath += Path.DirectorySeparatorChar;
            }

            string overridePath = Path.Combine(Path.GetDirectoryName(zipFile), Path.GetFileNameWithoutExtension(zipFile)) + Path.DirectorySeparatorChar;

            string loaderDll     = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TaskManager.Loader.dll");
            string tempLoaderDll = Path.Combine(tempPath, "TaskManager.Loader.dll");
            string commonDll     = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TaskManager.Common.dll");
            string tempCommonDll = Path.Combine(tempPath, "TaskManager.Common.dll");

            List <string> dependencies = new List <string>();

            DirectoryInfo directoryInfo = Directory.CreateDirectory(tempPath);

            try
            {
                using (Stream fileStream = File.Open(zipFile, FileMode.Open, FileAccess.Read))
                {
                    using (ZipArchive zip = new ZipArchive(fileStream, ZipArchiveMode.Read))
                    {
                        var directory = zip.Entries;

                        foreach (var compressedFile in directory)
                        {
                            string destinationFile = Path.Combine(tempPath, compressedFile.FullName);
                            string overrideFile    = Path.Combine(overridePath, compressedFile.FullName);
                            dependencies.Add(overrideFile);

                            compressedFile.ExtractToFile(destinationFile, true);
                        }
                    }
                }

                if (Directory.Exists(overridePath))
                {
                    foreach (string overrideFile in Directory.GetFiles(overridePath, "*.*", SearchOption.AllDirectories))
                    {
                        if (!dependencies.Contains(overrideFile))
                        {
                            dependencies.Add(overrideFile);
                        }

                        dependencies.Add(Path.Combine(overridePath, overrideFile.Replace(tempPath, string.Empty)));

                        string relativeName    = overrideFile.Replace(overridePath, string.Empty);
                        string destination     = Path.Combine(tempPath, relativeName);
                        string destinationPath = Path.GetDirectoryName(destination);

                        if (!Directory.Exists(destinationPath))
                        {
                            Directory.CreateDirectory(destinationPath);
                        }

                        File.Copy(overrideFile, destination, true);
                    }
                }

                List <string> possibleFiles = new List <string>();
                foreach (string moduleFile in Directory.GetFiles(tempPath, "*" + ModuleFileDefaultExtension, SearchOption.AllDirectories))
                {
                    string xmlFile = Path.ChangeExtension(moduleFile, ConfigFileDefaultExtension);

                    if (File.Exists(xmlFile))
                    {
                        possibleFiles.Add(moduleFile);
                    }
                }

                File.Copy(loaderDll, tempLoaderDll, true);
                File.Copy(commonDll, tempCommonDll, true);

                foreach (string dllFile in possibleFiles)
                {
                    string xmlFile = Path.ChangeExtension(dllFile, ConfigFileDefaultExtension);

                    if (File.Exists(xmlFile))
                    {
                        if (!xmlFile.IsValidConfigurationFile())
                        {
                            continue;
                        }

                        string modulePath = Path.GetDirectoryName(dllFile);

                        string[] files = Directory.GetFiles(modulePath, "*.*", SearchOption.AllDirectories);

                        AppDomainSetup domainSetup = new AppDomainSetup();
                        domainSetup.ShadowCopyFiles   = "true";
                        domainSetup.ApplicationBase   = tempPath;
                        domainSetup.ConfigurationFile = dllFile + ".config";

                        AppDomain domain = AppDomain.CreateDomain(dllFile, null, domainSetup);

                        TaskWrapper[] tasks = new TaskWrapper[0];

                        try
                        {
                            TaskManagerService.Logger.Log(string.Format("Module found: '{0}', configuration file: '{1}', scanning assembly for tasks...", dllFile, xmlFile));

                            AssemblyName loaderAssemblyName = AssemblyName.GetAssemblyName(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TaskManager.Loader.dll"));
                            Loader       loader             = (Loader)domain.CreateInstanceAndUnwrap(loaderAssemblyName.ToString(), "TaskManager.Loader");

                            tasks = loader.LoadAndConfigure(dllFile, xmlFile, TaskManagerService.Logger, AppDomain.CurrentDomain.BaseDirectory);

                            ModuleData newModule = new ModuleData();
                            newModule.BasePath     = overridePath;
                            newModule.Tasks        = tasks;
                            newModule.DllFile      = dllFile;
                            newModule.XmlFile      = xmlFile;
                            newModule.ZipFile      = zipFile;
                            newModule.ZipDirectory = tempPath;
                            newModule.Files        = new List <string>(files);
                            newModule.Files.AddRange(dependencies);
                            newModule.Files.Add(zipFile);
                            newModule.Domain = domain;

                            if (startImmediately)
                            {
                                foreach (TaskWrapper task in newModule.Tasks)
                                {
                                    TaskSupervisor.ScheduleTask(task);
                                }
                            }

                            _moduleList.Add(newModule);
                        }
                        catch (Exception ex)
                        {
                            foreach (TaskWrapper task in tasks)
                            {
                                try
                                {
                                    TaskSupervisor.RemoveTask(task);
                                }
                                catch
                                {
                                }
                            }

                            AppDomain.Unload(domain);

                            TaskManagerService.Logger.Log(string.Format("Unable to load module '{0}' from zipped file '{1}'.", dllFile, zipFile), ex);
                        }
                    }
                }

                foreach (ModuleData module in _moduleList)
                {
                    if (module.ZipFile == zipFile)
                    {
                        return;
                    }
                }

                throw new Exception(string.Format("Unable to find tasks in zipped file '{0}'.", zipFile));
            }
            catch
            {
                try
                {
                    Directory.Delete(tempPath, true);
                }
                catch (Exception ex)
                {
                    TaskManagerService.Logger.Log(string.Format("Unable to remove temporary directory '{0}'.", tempPath), ex);
                }

                throw;
            }
        }