private int Run(string[] args) { AssemblyInformationalVersionAttribute versionAttribute = Attribute.GetCustomAttribute(typeof(Program).Assembly, typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute; Console.WriteLine("Wyam version {0}", versionAttribute == null ? "unknown" : versionAttribute.InformationalVersion); // Parse the command line bool hasParseArgsErrors; if (!ParseArgs(args, out hasParseArgsErrors)) { return hasParseArgsErrors ? (int)ExitCode.CommandLineError : (int)ExitCode.Normal; } // It's not a serious console app unless there's some ASCII art OutputLogo(); // Fix the root folder and other files _rootFolder = _rootFolder == null ? Environment.CurrentDirectory : Path.Combine(Environment.CurrentDirectory, _rootFolder); _logFile = _logFile == null ? null : Path.Combine(_rootFolder, _logFile); _configFile = string.IsNullOrWhiteSpace(_configFile) ? Path.Combine(_rootFolder, "config.wyam") : Path.Combine(_rootFolder, _configFile); // Get the engine Engine engine = GetEngine(); if (engine == null) { return (int)ExitCode.CommandLineError; } // Pause if (_pause) { engine.Trace.Information("Pause requested, hit any key to continue"); Console.ReadKey(); } // Configure and execute if (!Configure(engine)) { return (int)ExitCode.ConfigurationError; } Console.WriteLine("Root folder: {0}", engine.RootFolder); Console.WriteLine("Input folder: {0}", engine.InputFolder); Console.WriteLine("Output folder: {0}", engine.OutputFolder); if (!Execute(engine)) { return (int)ExitCode.ExecutionError; } bool messagePump = false; // Start the preview server IDisposable previewServer = null; if (_preview) { messagePump = true; try { engine.Trace.Information("Preview server listening on port {0} and serving from {1}", _previewPort, engine.OutputFolder); previewServer = Preview(engine); } catch (Exception ex) { engine.Trace.Critical("Error while running preview server: {0}", ex.Message); } } // Start the watchers IDisposable inputFolderWatcher = null; IDisposable configFileWatcher = null; if (_watch) { messagePump = true; engine.Trace.Information("Watching folder {0}", engine.InputFolder); inputFolderWatcher = new ActionFileSystemWatcher(engine.OutputFolder, engine.InputFolder, true, "*.*", path => { _changedFiles.Enqueue(path); _messageEvent.Set(); }); if (_configFile != null) { engine.Trace.Information("Watching configuration file {0}", _configFile); configFileWatcher = new ActionFileSystemWatcher(engine.OutputFolder, Path.GetDirectoryName(_configFile), false, Path.GetFileName(_configFile), path => { if (path == _configFile) { _newEngine.Set(); _messageEvent.Set(); } }); } } // Start the message pump if an async process is running ExitCode exitCode = ExitCode.Normal; if (messagePump) { // Start the key listening thread engine.Trace.Information("Hit any key to exit"); var thread = new Thread(() => { Console.ReadKey(); _exit.Set(); _messageEvent.Set(); }) { IsBackground = true }; thread.Start(); // Wait for activity while (true) { _messageEvent.WaitOne(); // Blocks the current thread until a signal if (_exit) { break; } // See if we need a new engine if (_newEngine) { // Get a new engine engine.Trace.Information("Configuration file {0} has changed, re-running", _configFile); engine.Dispose(); engine = GetEngine(); // Configure and execute if (!Configure(engine)) { exitCode = ExitCode.ConfigurationError; break; } Console.WriteLine("Root folder: {0}", engine.RootFolder); Console.WriteLine("Input folder: {0}", engine.InputFolder); Console.WriteLine("Output folder: {0}", engine.OutputFolder); if (!Execute(engine)) { exitCode = ExitCode.ExecutionError; break; } // Clear the changed files since we just re-ran string changedFile; while (_changedFiles.TryDequeue(out changedFile)) { } _newEngine.Unset(); } else { // Execute if files have changed HashSet<string> changedFiles = new HashSet<string>(); string changedFile; while (_changedFiles.TryDequeue(out changedFile)) { if (changedFiles.Add(changedFile)) { engine.Trace.Verbose("{0} has changed", changedFile); } } if (changedFiles.Count > 0) { engine.Trace.Information("{0} files have changed, re-executing", changedFiles.Count); if (!Execute(engine)) { exitCode = ExitCode.ExecutionError; break; } } } // Check one more time for exit if (_exit) { break; } engine.Trace.Information("Hit any key to exit"); _messageEvent.Reset(); } // Shutdown engine.Trace.Information("Shutting down"); engine.Dispose(); inputFolderWatcher?.Dispose(); configFileWatcher?.Dispose(); previewServer?.Dispose(); } return (int)exitCode; }
private int Run(string[] args) { // Add a default trace listener Trace.AddListener(new SimpleColorConsoleTraceListener { TraceOutputOptions = System.Diagnostics.TraceOptions.None }); // Output version info AssemblyInformationalVersionAttribute versionAttribute = Attribute.GetCustomAttribute(typeof(Program).Assembly, typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute; Trace.Information("Wyam version {0}", versionAttribute == null ? "unknown" : versionAttribute.InformationalVersion); // It's not a serious console app unless there's some ASCII art OutputLogo(); // Parse the command line try { bool hasParseArgsErrors; if (!_settings.ParseArgs(args, _preprocessor, out hasParseArgsErrors)) { return(hasParseArgsErrors ? (int)ExitCode.CommandLineError : (int)ExitCode.Normal); } // Was help for the preprocessor directives requested? if (_settings.HelpDirectives) { Console.WriteLine("Available preprocessor directives:"); foreach (IDirective directive in _preprocessor.Directives) { Console.WriteLine(); Console.WriteLine($"{directive.Description}:"); Console.WriteLine(string.Join(", ", directive.DirectiveNames.Select(x => "#" + x))); Console.WriteLine(directive.GetHelpText()); } return((int)ExitCode.Normal); } } catch (Exception ex) { Trace.Error("Error while parsing command line: {0}", ex.Message); if (Trace.Level == System.Diagnostics.SourceLevels.Verbose) { Trace.Error("Stack trace:{0}{1}", Environment.NewLine, ex.StackTrace); } return((int)ExitCode.CommandLineError); } // Fix the root folder and other files DirectoryPath currentDirectory = Environment.CurrentDirectory; _settings.RootPath = _settings.RootPath == null ? currentDirectory : currentDirectory.Combine(_settings.RootPath); _settings.LogFilePath = _settings.LogFilePath == null ? null : _settings.RootPath.CombineFile(_settings.LogFilePath); _settings.ConfigFilePath = _settings.RootPath.CombineFile(_settings.ConfigFilePath ?? "config.wyam"); // Set up the log file if (_settings.LogFilePath != null) { Trace.AddListener(new SimpleFileTraceListener(_settings.LogFilePath.FullPath)); } // Prepare engine metadata if (!_settings.VerifyConfig && _settings.GlobalMetadataArgs != null && _settings.GlobalMetadataArgs.Count > 0) { try { _settings.GlobalMetadata = GlobalMetadataParser.Parse(_settings.GlobalMetadataArgs); } catch (MetadataParseException ex) { Trace.Error("Error while parsing metadata: {0}", ex.Message); if (Trace.Level == System.Diagnostics.SourceLevels.Verbose) { Trace.Error("Stack trace:{0}{1}", Environment.NewLine, ex.StackTrace); } return((int)ExitCode.CommandLineError); } // Not used anymore, release resources. _settings.GlobalMetadataArgs = null; } // Get the engine and configurator EngineManager engineManager = GetEngineManager(); if (engineManager == null) { return((int)ExitCode.CommandLineError); } // Pause if (_settings.Pause) { Trace.Information("Pause requested, hit any key to continue"); Console.ReadKey(); } // Configure and execute if (!engineManager.Configure()) { return((int)ExitCode.ConfigurationError); } if (_settings.VerifyConfig) { Trace.Information("No errors. Exiting."); return((int)ExitCode.Normal); } Trace.Information($"Root path:{Environment.NewLine} {engineManager.Engine.FileSystem.RootPath}"); Trace.Information($"Input path(s):{Environment.NewLine} {string.Join(Environment.NewLine + " ", engineManager.Engine.FileSystem.InputPaths)}"); Trace.Information($"Output path:{Environment.NewLine} {engineManager.Engine.FileSystem.OutputPath}"); if (!engineManager.Execute()) { return((int)ExitCode.ExecutionError); } bool messagePump = false; // Start the preview server IDisposable previewServer = null; if (_settings.Preview) { messagePump = true; try { DirectoryPath previewPath = _settings.PreviewRoot == null ? engineManager.Engine.FileSystem.GetOutputDirectory().Path : engineManager.Engine.FileSystem.GetOutputDirectory(_settings.PreviewRoot).Path; Trace.Information("Preview server listening on port {0} and serving from path {1}", _settings.PreviewPort, previewPath); previewServer = Preview(previewPath); } catch (Exception ex) { Trace.Critical("Error while running preview server: {0}", ex.Message); } } // Start the watchers IDisposable inputFolderWatcher = null; IDisposable configFileWatcher = null; if (_settings.Watch) { messagePump = true; Trace.Information("Watching paths(s) {0}", string.Join(", ", engineManager.Engine.FileSystem.InputPaths)); inputFolderWatcher = new ActionFileSystemWatcher(engineManager.Engine.FileSystem.GetOutputDirectory().Path, engineManager.Engine.FileSystem.GetInputDirectories().Select(x => x.Path), true, "*.*", path => { _changedFiles.Enqueue(path); _messageEvent.Set(); }); if (_settings.ConfigFilePath != null) { Trace.Information("Watching configuration file {0}", _settings.ConfigFilePath); configFileWatcher = new ActionFileSystemWatcher(engineManager.Engine.FileSystem.GetOutputDirectory().Path, new[] { _settings.ConfigFilePath.Directory }, false, _settings.ConfigFilePath.FileName.FullPath, path => { FilePath filePath = new FilePath(path); if (_settings.ConfigFilePath.Equals(filePath)) { _newEngine.Set(); _messageEvent.Set(); } }); } } // Start the message pump if an async process is running ExitCode exitCode = ExitCode.Normal; if (messagePump) { // Start the key listening thread Trace.Information("Hit any key to exit"); var thread = new Thread(() => { Console.ReadKey(); _exit.Set(); _messageEvent.Set(); }) { IsBackground = true }; thread.Start(); // Wait for activity while (true) { _messageEvent.WaitOne(); // Blocks the current thread until a signal if (_exit) { break; } // See if we need a new engine if (_newEngine) { // Get a new engine Trace.Information("Configuration file {0} has changed, re-running", _settings.ConfigFilePath); engineManager.Dispose(); engineManager = GetEngineManager(); // Configure and execute if (!engineManager.Configure()) { exitCode = ExitCode.ConfigurationError; break; } Console.WriteLine($"Root path:{Environment.NewLine} {engineManager.Engine.FileSystem.RootPath}"); Console.WriteLine($"Input path(s):{Environment.NewLine} {string.Join(Environment.NewLine + " ", engineManager.Engine.FileSystem.InputPaths)}"); Console.WriteLine($"Root path:{Environment.NewLine} {engineManager.Engine.FileSystem.OutputPath}"); if (!engineManager.Execute()) { exitCode = ExitCode.ExecutionError; break; } // Clear the changed files since we just re-ran string changedFile; while (_changedFiles.TryDequeue(out changedFile)) { } _newEngine.Unset(); } else { // Execute if files have changed HashSet <string> changedFiles = new HashSet <string>(); string changedFile; while (_changedFiles.TryDequeue(out changedFile)) { if (changedFiles.Add(changedFile)) { Trace.Verbose("{0} has changed", changedFile); } } if (changedFiles.Count > 0) { Trace.Information("{0} files have changed, re-executing", changedFiles.Count); if (!engineManager.Execute()) { exitCode = ExitCode.ExecutionError; break; } } } // Check one more time for exit if (_exit) { break; } Trace.Information("Hit any key to exit"); _messageEvent.Reset(); } // Shutdown Trace.Information("Shutting down"); engineManager.Dispose(); inputFolderWatcher?.Dispose(); configFileWatcher?.Dispose(); previewServer?.Dispose(); } return((int)exitCode); }
private void Run(string[] args) { // Parse the command line if (!ParseArgs(args)) { return; } // Fix the root folder and other files _rootFolder = _rootFolder == null ? Environment.CurrentDirectory : Path.Combine(Environment.CurrentDirectory, _rootFolder); _logFile = _logFile == null ? null : Path.Combine(_rootFolder, _logFile); _configFile = string.IsNullOrWhiteSpace(_configFile) ? Path.Combine(_rootFolder, "config.wyam") : Path.Combine(_rootFolder, _configFile); // Get the engine Engine engine = GetEngine(); if (engine == null) { return; } // Pause if (_pause) { engine.Trace.Information("Pause requested, hit any key to continue."); Console.ReadKey(); } // Configure and execute if (!Configure(engine)) { return; } if (!Execute(engine)) { return; } bool messagePump = false; // Start the preview server IDisposable previewServer = null; if (_preview) { messagePump = true; try { engine.Trace.Information("Preview server listening on port {0} and serving from {1}...", _previewPort, engine.OutputFolder); previewServer = Preview(engine); } catch (Exception ex) { engine.Trace.Critical("Error while running preview server: {0}.", ex.Message); } } // Start the watchers IDisposable inputFolderWatcher = null; IDisposable configFileWatcher = null; if (_watch) { messagePump = true; engine.Trace.Information("Watching folder {0}...", engine.InputFolder); inputFolderWatcher = new ActionFileSystemWatcher(engine.InputFolder, true, "*.*", path => { _changedFiles.Enqueue(path); _messageEvent.Set(); }); if (_configFile != null) { engine.Trace.Information("Watching configuration file {0}...", _configFile); configFileWatcher = new ActionFileSystemWatcher(Path.GetDirectoryName(_configFile), false, Path.GetFileName(_configFile), path => { if (path == _configFile) { _newEngine.Set(); _messageEvent.Set(); } }); } } // Start the message pump if an async process is running if (messagePump) { // Start the key listening thread engine.Trace.Information("Hit any key to exit..."); var thread = new Thread(() => { Console.ReadKey(); _exit.Set(); _messageEvent.Set(); }) { IsBackground = true }; thread.Start(); // Wait for activity while (true) { _messageEvent.WaitOne(); // Blocks the current thread until a signal if (_exit) { break; } // See if we need a new engine if (_newEngine) { // Get a new engine engine.Trace.Information("Configuration file {0} has changed, re-running...", _configFile); engine.Dispose(); engine = GetEngine(); // Configure and execute if (!Configure(engine)) { break; } if (!Execute(engine)) { break; } // Clear the changed files since we just re-ran string changedFile; while (_changedFiles.TryDequeue(out changedFile)) { } _newEngine.Unset(); } else { // Execute if files have changed HashSet<string> changedFiles = new HashSet<string>(); string changedFile; while (_changedFiles.TryDequeue(out changedFile)) { if (changedFiles.Add(changedFile)) { engine.Trace.Verbose("{0} has changed.", changedFile); } } if (changedFiles.Count > 0) { engine.Trace.Information("{0} files have changed, re-executing...", changedFiles.Count); if (!Execute(engine)) { break; } } } // Check one more time for exit if (_exit) { break; } engine.Trace.Information("Hit any key to exit..."); _messageEvent.Reset(); } // Shutdown engine.Trace.Information("Shutting down..."); engine.Dispose(); if (inputFolderWatcher != null) { inputFolderWatcher.Dispose(); } if (configFileWatcher != null) { configFileWatcher.Dispose(); } if (previewServer != null) { previewServer.Dispose(); } } }
private void Run(string[] args) { AssemblyInformationalVersionAttribute versionAttribute = Attribute.GetCustomAttribute(typeof(Program).Assembly, typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute; Console.WriteLine("Wyam version {0}", versionAttribute == null ? "unknown" : versionAttribute.InformationalVersion); // Parse the command line if (!ParseArgs(args)) { return; } // It's not a serious console app unless there's some ASCII art OutputLogo(); // Fix the root folder and other files _rootFolder = _rootFolder == null ? Environment.CurrentDirectory : Path.Combine(Environment.CurrentDirectory, _rootFolder); _logFile = _logFile == null ? null : Path.Combine(_rootFolder, _logFile); _configFile = string.IsNullOrWhiteSpace(_configFile) ? Path.Combine(_rootFolder, "config.wyam") : Path.Combine(_rootFolder, _configFile); // Get the engine Engine engine = GetEngine(); if (engine == null) { return; } // Pause if (_pause) { engine.Trace.Information("Pause requested, hit any key to continue"); Console.ReadKey(); } // Configure and execute if (!Configure(engine)) { return; } Console.WriteLine("Root folder: {0}", engine.RootFolder); Console.WriteLine("Input folder: {0}", engine.InputFolder); Console.WriteLine("Output folder: {0}", engine.OutputFolder); if (!Execute(engine)) { return; } bool messagePump = false; // Start the preview server IDisposable previewServer = null; if (_preview) { messagePump = true; try { engine.Trace.Information("Preview server listening on port {0} and serving from {1}", _previewPort, engine.OutputFolder); previewServer = Preview(engine); } catch (Exception ex) { engine.Trace.Critical("Error while running preview server: {0}", ex.Message); } } // Start the watchers IDisposable inputFolderWatcher = null; IDisposable configFileWatcher = null; if (_watch) { messagePump = true; engine.Trace.Information("Watching folder {0}", engine.InputFolder); inputFolderWatcher = new ActionFileSystemWatcher(engine.InputFolder, true, "*.*", path => { _changedFiles.Enqueue(path); _messageEvent.Set(); }); if (_configFile != null) { engine.Trace.Information("Watching configuration file {0}", _configFile); configFileWatcher = new ActionFileSystemWatcher(Path.GetDirectoryName(_configFile), false, Path.GetFileName(_configFile), path => { if (path == _configFile) { _newEngine.Set(); _messageEvent.Set(); } }); } } // Start the message pump if an async process is running if (messagePump) { // Start the key listening thread engine.Trace.Information("Hit any key to exit"); var thread = new Thread(() => { Console.ReadKey(); _exit.Set(); _messageEvent.Set(); }) { IsBackground = true }; thread.Start(); // Wait for activity while (true) { _messageEvent.WaitOne(); // Blocks the current thread until a signal if (_exit) { break; } // See if we need a new engine if (_newEngine) { // Get a new engine engine.Trace.Information("Configuration file {0} has changed, re-running", _configFile); engine.Dispose(); engine = GetEngine(); // Configure and execute if (!Configure(engine)) { break; } Console.WriteLine("Root folder: {0}", engine.RootFolder); Console.WriteLine("Input folder: {0}", engine.InputFolder); Console.WriteLine("Output folder: {0}", engine.OutputFolder); if (!Execute(engine)) { break; } // Clear the changed files since we just re-ran string changedFile; while (_changedFiles.TryDequeue(out changedFile)) { } _newEngine.Unset(); } else { // Execute if files have changed HashSet <string> changedFiles = new HashSet <string>(); string changedFile; while (_changedFiles.TryDequeue(out changedFile)) { if (changedFiles.Add(changedFile)) { engine.Trace.Verbose("{0} has changed", changedFile); } } if (changedFiles.Count > 0) { engine.Trace.Information("{0} files have changed, re-executing", changedFiles.Count); if (!Execute(engine)) { break; } } } // Check one more time for exit if (_exit) { break; } engine.Trace.Information("Hit any key to exit"); _messageEvent.Reset(); } // Shutdown engine.Trace.Information("Shutting down"); engine.Dispose(); inputFolderWatcher?.Dispose(); configFileWatcher?.Dispose(); previewServer?.Dispose(); } }
private int Run(string[] args) { AssemblyInformationalVersionAttribute versionAttribute = Attribute.GetCustomAttribute(typeof(Program).Assembly, typeof(AssemblyInformationalVersionAttribute)) as AssemblyInformationalVersionAttribute; Console.WriteLine("Wyam version {0}", versionAttribute == null ? "unknown" : versionAttribute.InformationalVersion); // Parse the command line bool hasParseArgsErrors; if (!ParseArgs(args, out hasParseArgsErrors)) { return hasParseArgsErrors ? (int)ExitCode.CommandLineError : (int)ExitCode.Normal; } // It's not a serious console app unless there's some ASCII art OutputLogo(); // Fix the root folder and other files DirectoryPath currentDirectory = Environment.CurrentDirectory; _rootPath = _rootPath == null ? currentDirectory : currentDirectory.Combine(_rootPath); _logFilePath = _logFilePath == null ? null : _rootPath.CombineFile(_logFilePath); _configFilePath = _rootPath.CombineFile(_configFilePath ?? "config.wyam"); // Get the engine Engine engine = GetEngine(); if (engine == null) { return (int)ExitCode.CommandLineError; } // Pause if (_pause) { Trace.Information("Pause requested, hit any key to continue"); Console.ReadKey(); } // Configure and execute if (!Configure(engine)) { return (int)ExitCode.ConfigurationError; } if (_verifyConfig) { Trace.Information("No errors. Exiting."); return (int)ExitCode.Normal; } Console.WriteLine($"Root path:{Environment.NewLine} {engine.FileSystem.RootPath}"); Console.WriteLine($"Input path(s):{Environment.NewLine} {string.Join(Environment.NewLine + " ", engine.FileSystem.InputPaths)}"); Console.WriteLine($"Output path:{Environment.NewLine} {engine.FileSystem.OutputPath}"); if (!Execute(engine)) { return (int)ExitCode.ExecutionError; } bool messagePump = false; // Start the preview server IDisposable previewServer = null; if (_preview) { messagePump = true; try { var rootPath = _previewRoot == null ? engine.FileSystem.GetOutputDirectory().Path.FullPath : _previewRoot.FullPath; Trace.Information("Preview server listening on port {0} and serving from path {1}", _previewPort, rootPath); previewServer = Preview(engine, rootPath); } catch (Exception ex) { Trace.Critical("Error while running preview server: {0}", ex.Message); } } // Start the watchers IDisposable inputFolderWatcher = null; IDisposable configFileWatcher = null; if (_watch) { messagePump = true; Trace.Information("Watching paths(s) {0}", string.Join(", ", engine.FileSystem.InputPaths)); inputFolderWatcher = new ActionFileSystemWatcher(engine.FileSystem.GetOutputDirectory().Path, engine.FileSystem.GetInputDirectories().Select(x => x.Path), true, "*.*", path => { _changedFiles.Enqueue(path); _messageEvent.Set(); }); if (_configFilePath != null) { Trace.Information("Watching configuration file {0}", _configFilePath); Engine closureEngine = engine; configFileWatcher = new ActionFileSystemWatcher(engine.FileSystem.GetOutputDirectory().Path, new[] { _configFilePath.GetDirectory() }, false, _configFilePath.GetFilename().FullPath, path => { if (closureEngine.FileSystem.PathComparer.Equals((FilePath)path, _configFilePath)) { _newEngine.Set(); _messageEvent.Set(); } }); } } // Start the message pump if an async process is running ExitCode exitCode = ExitCode.Normal; if (messagePump) { // Start the key listening thread Trace.Information("Hit any key to exit"); var thread = new Thread(() => { Console.ReadKey(); _exit.Set(); _messageEvent.Set(); }) { IsBackground = true }; thread.Start(); // Wait for activity while (true) { _messageEvent.WaitOne(); // Blocks the current thread until a signal if (_exit) { break; } // See if we need a new engine if (_newEngine) { // Get a new engine Trace.Information("Configuration file {0} has changed, re-running", _configFilePath); engine.Dispose(); engine = GetEngine(); // Configure and execute if (!Configure(engine)) { exitCode = ExitCode.ConfigurationError; break; } Console.WriteLine($"Root path:{Environment.NewLine} {engine.FileSystem.RootPath}"); Console.WriteLine($"Input path(s):{Environment.NewLine} {string.Join(Environment.NewLine + " ", engine.FileSystem.InputPaths)}"); Console.WriteLine($"Root path:{Environment.NewLine} {engine.FileSystem.OutputPath}"); if (!Execute(engine)) { exitCode = ExitCode.ExecutionError; break; } // Clear the changed files since we just re-ran string changedFile; while (_changedFiles.TryDequeue(out changedFile)) { } _newEngine.Unset(); } else { // Execute if files have changed HashSet<string> changedFiles = new HashSet<string>(); string changedFile; while (_changedFiles.TryDequeue(out changedFile)) { if (changedFiles.Add(changedFile)) { Trace.Verbose("{0} has changed", changedFile); } } if (changedFiles.Count > 0) { Trace.Information("{0} files have changed, re-executing", changedFiles.Count); if (!Execute(engine)) { exitCode = ExitCode.ExecutionError; break; } } } // Check one more time for exit if (_exit) { break; } Trace.Information("Hit any key to exit"); _messageEvent.Reset(); } // Shutdown Trace.Information("Shutting down"); engine.Dispose(); inputFolderWatcher?.Dispose(); configFileWatcher?.Dispose(); previewServer?.Dispose(); } return (int)exitCode; }