private void RunApplication(string action) { if (watcher == null) { watcher = new FileSystemWatcher(AppDomain.CurrentDomain.BaseDirectory, "*.dll"); watcher.Changed += delegate(object sender, FileSystemEventArgs e) { StopRunner(string.Format(System.Globalization.CultureInfo.CurrentCulture,"One or more DLLs have changed - waiting {0}s", restartTime)); waitTimer.Stop(); waitTimer.Start(); }; watcher.EnableRaisingEvents = true; watcher.NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.LastWrite | NotifyFilters.Size; } // Allow the user to turn shadow-copying off var setting = ConfigurationManager.AppSettings["ShadowCopy"] ?? string.Empty; var useShadowCopying = !(string.Equals(setting, "off", StringComparison.OrdinalIgnoreCase) || string.Equals(setting, "false", StringComparison.OrdinalIgnoreCase)); try { this.runnerDomain = CreateNewDomain(useShadowCopying); } catch (FileLoadException) { // Unable to use shadow-copying (no user profile?), therefore turn off shadow-copying useShadowCopying = false; this.runnerDomain = CreateNewDomain(useShadowCopying); } runner = runnerDomain.CreateInstanceFromAndUnwrap(Assembly.GetExecutingAssembly().Location, typeof(AppRunner).FullName) as AppRunner; try { runner.Run(action, useShadowCopying); } catch (SerializationException) { var configFilename = ConfigurationManager.AppSettings["ccnet.config"]; configFilename = string.IsNullOrEmpty(configFilename) ? Path.Combine(Environment.CurrentDirectory, "ccnet.log") : configFilename; throw new ApplicationException( string.Format(System.Globalization.CultureInfo.CurrentCulture,"A fatal error has occurred while starting CCService. Please check '{0}' for any details.", configFilename)); } }
private void StopRunner(string reason) { AppRunner runnerToStop = null; // Retrieve the runner in a thread-safe block and then clear it so we are not holding up otherwise processing lock (lockObject) { if (runner != null) { runnerToStop = runner; runner = null; } } // If a runner needs to be stopped, do it here if (runnerToStop != null) { runnerToStop.Stop(reason); AppDomain.Unload(runnerDomain); } }