From f32149681530256c9ceef879bbe21711383b500b Mon Sep 17 00:00:00 2001 From: dbuechel Date: Fri, 19 Jan 2018 14:04:12 +0100 Subject: [PATCH] SEBWIN-219: Finished basic version of configuration operation. --- .../Behaviour/Operations/BrowserOperation.cs | 1 + .../Operations/ClientControllerOperation.cs | 1 + .../Operations/ClipboardOperation.cs | 1 + .../Operations/DisplayMonitorOperation.cs | 1 + .../KeyboardInterceptorOperation.cs | 1 + .../Operations/MouseInterceptorOperation.cs | 1 + .../Operations/ProcessMonitorOperation.cs | 1 + .../Behaviour/Operations/TaskbarOperation.cs | 1 + .../Operations/WindowMonitorOperation.cs | 1 + .../Behaviour/IOperation.cs | 5 ++ .../Behaviour/ShutdownControllerTests.cs | 24 ++++++++ .../Behaviour/StartupControllerTests.cs | 38 +++++++++++- .../Behaviour/Operations/I18nOperation.cs | 1 + .../Behaviour/ShutdownController.cs | 6 +- .../Behaviour/StartupController.cs | 56 ++++++++++-------- .../Operations/ConfigurationOperationTests.cs | 33 +++++++++++ SafeExamBrowser.Runtime/App.cs | 24 ++++++++ .../Operations/ConfigurationOperation.cs | 39 +++++++++---- .../Operations/RuntimeControllerOperation.cs | 1 + SafeExamBrowser.Runtime/CompositionRoot.cs | 58 ++++++++++--------- 20 files changed, 229 insertions(+), 65 deletions(-) diff --git a/SafeExamBrowser.Client/Behaviour/Operations/BrowserOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/BrowserOperation.cs index 4653bfa4..26073740 100644 --- a/SafeExamBrowser.Client/Behaviour/Operations/BrowserOperation.cs +++ b/SafeExamBrowser.Client/Behaviour/Operations/BrowserOperation.cs @@ -23,6 +23,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations private ITaskbar taskbar; private IUserInterfaceFactory uiFactory; + public bool AbortStartup { get; private set; } public ISplashScreen SplashScreen { private get; set; } public BrowserOperation( diff --git a/SafeExamBrowser.Client/Behaviour/Operations/ClientControllerOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/ClientControllerOperation.cs index 28696a65..bbd34ceb 100644 --- a/SafeExamBrowser.Client/Behaviour/Operations/ClientControllerOperation.cs +++ b/SafeExamBrowser.Client/Behaviour/Operations/ClientControllerOperation.cs @@ -19,6 +19,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations private ILogger logger; private IClientController controller; + public bool AbortStartup { get; private set; } public ISplashScreen SplashScreen { private get; set; } public ClientControllerOperation(IClientController controller, ILogger logger) diff --git a/SafeExamBrowser.Client/Behaviour/Operations/ClipboardOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/ClipboardOperation.cs index 61d68248..a33fef9a 100644 --- a/SafeExamBrowser.Client/Behaviour/Operations/ClipboardOperation.cs +++ b/SafeExamBrowser.Client/Behaviour/Operations/ClipboardOperation.cs @@ -19,6 +19,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations private ILogger logger; private INativeMethods nativeMethods; + public bool AbortStartup { get; private set; } public ISplashScreen SplashScreen { private get; set; } public ClipboardOperation(ILogger logger, INativeMethods nativeMethods) diff --git a/SafeExamBrowser.Client/Behaviour/Operations/DisplayMonitorOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/DisplayMonitorOperation.cs index a23bd653..3a0df0da 100644 --- a/SafeExamBrowser.Client/Behaviour/Operations/DisplayMonitorOperation.cs +++ b/SafeExamBrowser.Client/Behaviour/Operations/DisplayMonitorOperation.cs @@ -21,6 +21,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations private ILogger logger; private ITaskbar taskbar; + public bool AbortStartup { get; private set; } public ISplashScreen SplashScreen { private get; set; } public DisplayMonitorOperation(IDisplayMonitor displayMonitor, ILogger logger, ITaskbar taskbar) diff --git a/SafeExamBrowser.Client/Behaviour/Operations/KeyboardInterceptorOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/KeyboardInterceptorOperation.cs index ee0e84e3..23e01fa3 100644 --- a/SafeExamBrowser.Client/Behaviour/Operations/KeyboardInterceptorOperation.cs +++ b/SafeExamBrowser.Client/Behaviour/Operations/KeyboardInterceptorOperation.cs @@ -21,6 +21,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations private ILogger logger; private INativeMethods nativeMethods; + public bool AbortStartup { get; private set; } public ISplashScreen SplashScreen { private get; set; } public KeyboardInterceptorOperation( diff --git a/SafeExamBrowser.Client/Behaviour/Operations/MouseInterceptorOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/MouseInterceptorOperation.cs index 458c5539..d5d3c977 100644 --- a/SafeExamBrowser.Client/Behaviour/Operations/MouseInterceptorOperation.cs +++ b/SafeExamBrowser.Client/Behaviour/Operations/MouseInterceptorOperation.cs @@ -21,6 +21,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations private IMouseInterceptor mouseInterceptor; private INativeMethods nativeMethods; + public bool AbortStartup { get; private set; } public ISplashScreen SplashScreen { private get; set; } public MouseInterceptorOperation( diff --git a/SafeExamBrowser.Client/Behaviour/Operations/ProcessMonitorOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/ProcessMonitorOperation.cs index 7f36a955..9f76d206 100644 --- a/SafeExamBrowser.Client/Behaviour/Operations/ProcessMonitorOperation.cs +++ b/SafeExamBrowser.Client/Behaviour/Operations/ProcessMonitorOperation.cs @@ -19,6 +19,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations private ILogger logger; private IProcessMonitor processMonitor; + public bool AbortStartup { get; private set; } public ISplashScreen SplashScreen { private get; set; } public ProcessMonitorOperation(ILogger logger, IProcessMonitor processMonitor) diff --git a/SafeExamBrowser.Client/Behaviour/Operations/TaskbarOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/TaskbarOperation.cs index 56f78626..bb065669 100644 --- a/SafeExamBrowser.Client/Behaviour/Operations/TaskbarOperation.cs +++ b/SafeExamBrowser.Client/Behaviour/Operations/TaskbarOperation.cs @@ -31,6 +31,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations private IUserInterfaceFactory uiFactory; private IText text; + public bool AbortStartup { get; private set; } public ISplashScreen SplashScreen { private get; set; } public TaskbarOperation( diff --git a/SafeExamBrowser.Client/Behaviour/Operations/WindowMonitorOperation.cs b/SafeExamBrowser.Client/Behaviour/Operations/WindowMonitorOperation.cs index 7247ae90..f519388f 100644 --- a/SafeExamBrowser.Client/Behaviour/Operations/WindowMonitorOperation.cs +++ b/SafeExamBrowser.Client/Behaviour/Operations/WindowMonitorOperation.cs @@ -19,6 +19,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations private ILogger logger; private IWindowMonitor windowMonitor; + public bool AbortStartup { get; private set; } public ISplashScreen SplashScreen { private get; set; } public WindowMonitorOperation(ILogger logger, IWindowMonitor windowMonitor) diff --git a/SafeExamBrowser.Contracts/Behaviour/IOperation.cs b/SafeExamBrowser.Contracts/Behaviour/IOperation.cs index 77d161d4..b6c103e5 100644 --- a/SafeExamBrowser.Contracts/Behaviour/IOperation.cs +++ b/SafeExamBrowser.Contracts/Behaviour/IOperation.cs @@ -12,6 +12,11 @@ namespace SafeExamBrowser.Contracts.Behaviour { public interface IOperation { + /// + /// Determines whether the startup procedure to which this operation belongs should be aborted. + /// + bool AbortStartup { get; } + /// /// The splash screen to be used to show status information to the user. /// diff --git a/SafeExamBrowser.Core.UnitTests/Behaviour/ShutdownControllerTests.cs b/SafeExamBrowser.Core.UnitTests/Behaviour/ShutdownControllerTests.cs index 7466c072..35f0397a 100644 --- a/SafeExamBrowser.Core.UnitTests/Behaviour/ShutdownControllerTests.cs +++ b/SafeExamBrowser.Core.UnitTests/Behaviour/ShutdownControllerTests.cs @@ -57,8 +57,11 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour sut.FinalizeApplication(operations); operationA.Verify(o => o.Revert(), Times.Once); + operationA.Verify(o => o.Perform(), Times.Never); operationB.Verify(o => o.Revert(), Times.Once); + operationB.Verify(o => o.Perform(), Times.Never); operationC.Verify(o => o.Revert(), Times.Once); + operationC.Verify(o => o.Perform(), Times.Never); } [TestMethod] @@ -108,6 +111,27 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour operationC.Verify(o => o.Revert(), Times.Once); } + [TestMethod] + public void MustNotEvaluateAbortFlag() + { + var operationA = new Mock(); + var operationB = new Mock(); + var operationC = new Mock(); + var operations = new Queue(); + + operationB.SetupGet(o => o.AbortStartup).Returns(true); + + operations.Enqueue(operationA.Object); + operations.Enqueue(operationB.Object); + operations.Enqueue(operationC.Object); + + sut.FinalizeApplication(operations); + + operationA.Verify(o => o.Revert(), Times.Once); + operationB.Verify(o => o.Revert(), Times.Once); + operationC.Verify(o => o.Revert(), Times.Once); + } + [TestMethod] public void MustNotFailWithEmptyQueue() { diff --git a/SafeExamBrowser.Core.UnitTests/Behaviour/StartupControllerTests.cs b/SafeExamBrowser.Core.UnitTests/Behaviour/StartupControllerTests.cs index be07b786..b1527a95 100644 --- a/SafeExamBrowser.Core.UnitTests/Behaviour/StartupControllerTests.cs +++ b/SafeExamBrowser.Core.UnitTests/Behaviour/StartupControllerTests.cs @@ -12,7 +12,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; using SafeExamBrowser.Contracts.Behaviour; using SafeExamBrowser.Contracts.Configuration; -using SafeExamBrowser.Contracts.Configuration.Settings; using SafeExamBrowser.Contracts.I18n; using SafeExamBrowser.Contracts.Logging; using SafeExamBrowser.Contracts.UserInterface; @@ -45,6 +44,32 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour sut = new StartupController(loggerMock.Object, runtimeInfoMock.Object, systemInfoMock.Object, textMock.Object, uiFactoryMock.Object); } + [TestMethod] + public void MustCorrectlyAbortProcess() + { + var operationA = new Mock(); + var operationB = new Mock(); + var operationC = new Mock(); + var operations = new Queue(); + + operationB.SetupGet(o => o.AbortStartup).Returns(true); + + operations.Enqueue(operationA.Object); + operations.Enqueue(operationB.Object); + operations.Enqueue(operationC.Object); + + var result = sut.TryInitializeApplication(operations); + + operationA.Verify(o => o.Perform(), Times.Once); + operationA.Verify(o => o.Revert(), Times.Once); + operationB.Verify(o => o.Perform(), Times.Once); + operationB.Verify(o => o.Revert(), Times.Once); + operationC.Verify(o => o.Perform(), Times.Never); + operationC.Verify(o => o.Revert(), Times.Never); + + Assert.IsFalse(result); + } + [TestMethod] public void MustPerformOperations() { @@ -60,8 +85,11 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour var result = sut.TryInitializeApplication(operations); operationA.Verify(o => o.Perform(), Times.Once); + operationA.Verify(o => o.Revert(), Times.Never); operationB.Verify(o => o.Perform(), Times.Once); + operationB.Verify(o => o.Revert(), Times.Never); operationC.Verify(o => o.Perform(), Times.Once); + operationC.Verify(o => o.Revert(), Times.Never); Assert.IsTrue(result); } @@ -183,5 +211,13 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour Assert.IsTrue(result); } + + + [TestMethod] + public void MustNotFailInCaseOfUnexpectedError() + { + uiFactoryMock.Setup(l => l.CreateSplashScreen(It.IsAny(), It.IsAny())).Throws(new Exception()); + sut.TryInitializeApplication(new Queue()); + } } } diff --git a/SafeExamBrowser.Core/Behaviour/Operations/I18nOperation.cs b/SafeExamBrowser.Core/Behaviour/Operations/I18nOperation.cs index d15d58d6..7d8e1ccc 100644 --- a/SafeExamBrowser.Core/Behaviour/Operations/I18nOperation.cs +++ b/SafeExamBrowser.Core/Behaviour/Operations/I18nOperation.cs @@ -22,6 +22,7 @@ namespace SafeExamBrowser.Core.Behaviour.Operations private ILogger logger; private IText text; + public bool AbortStartup { get; private set; } public ISplashScreen SplashScreen { private get; set; } public I18nOperation(ILogger logger, IText text) diff --git a/SafeExamBrowser.Core/Behaviour/ShutdownController.cs b/SafeExamBrowser.Core/Behaviour/ShutdownController.cs index 2e660ef6..91c6799b 100644 --- a/SafeExamBrowser.Core/Behaviour/ShutdownController.cs +++ b/SafeExamBrowser.Core/Behaviour/ShutdownController.cs @@ -10,7 +10,6 @@ using System; using System.Collections.Generic; using SafeExamBrowser.Contracts.Behaviour; using SafeExamBrowser.Contracts.Configuration; -using SafeExamBrowser.Contracts.Configuration.Settings; using SafeExamBrowser.Contracts.I18n; using SafeExamBrowser.Contracts.Logging; using SafeExamBrowser.Contracts.UserInterface; @@ -88,8 +87,11 @@ namespace SafeExamBrowser.Core.Behaviour { logger.Info("--- Application successfully finalized! ---"); } + else + { + logger.Info("--- Shutdown procedure failed! ---"); + } - logger.Log($"{Environment.NewLine}# Application terminated at {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}"); splashScreen?.InvokeClose(); } } diff --git a/SafeExamBrowser.Core/Behaviour/StartupController.cs b/SafeExamBrowser.Core/Behaviour/StartupController.cs index c3aa04cd..d4bad03f 100644 --- a/SafeExamBrowser.Core/Behaviour/StartupController.cs +++ b/SafeExamBrowser.Core/Behaviour/StartupController.cs @@ -11,7 +11,6 @@ using System.Collections.Generic; using System.Linq; using SafeExamBrowser.Contracts.Behaviour; using SafeExamBrowser.Contracts.Configuration; -using SafeExamBrowser.Contracts.Configuration.Settings; using SafeExamBrowser.Contracts.I18n; using SafeExamBrowser.Contracts.Logging; using SafeExamBrowser.Contracts.UserInterface; @@ -40,35 +39,56 @@ namespace SafeExamBrowser.Core.Behaviour public bool TryInitializeApplication(Queue operations) { + var success = false; + try { Initialize(operations.Count); - Perform(operations); - Finish(); + success = Perform(operations); - return true; + if (!success) + { + RevertOperations(); + } + + Finish(success); } catch (Exception e) { LogAndShowException(e); - RevertOperations(); Finish(false); - - return false; } + + return success; } - private void Perform(Queue operations) + private bool Perform(Queue operations) { foreach (var operation in operations) { stack.Push(operation); - operation.SplashScreen = splashScreen; - operation.Perform(); + + try + { + operation.Perform(); + } + catch (Exception e) + { + LogAndShowException(e); + + return false; + } + + if (operation.AbortStartup) + { + return false; + } splashScreen.Progress(); } + + return true; } private void RevertOperations() @@ -92,17 +112,6 @@ namespace SafeExamBrowser.Core.Behaviour private void Initialize(int operationCount) { - var titleLine = $"/* {runtimeInfo.ProgramTitle}, Version {runtimeInfo.ProgramVersion}{Environment.NewLine}"; - var copyrightLine = $"/* {runtimeInfo.ProgramCopyright}{Environment.NewLine}"; - var emptyLine = $"/* {Environment.NewLine}"; - var githubLine = $"/* Please visit https://github.com/SafeExamBrowser for more information."; - - logger.Log($"{titleLine}{copyrightLine}{emptyLine}{githubLine}"); - logger.Log(string.Empty); - logger.Log($"# Application started at {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}"); - logger.Log($"# Running on {systemInfo.OperatingSystemInfo}"); - logger.Log(string.Empty); - logger.Info("--- Initiating startup procedure ---"); splashScreen = uiFactory.CreateSplashScreen(runtimeInfo, text); @@ -124,12 +133,13 @@ namespace SafeExamBrowser.Core.Behaviour { logger.Info("--- Application successfully initialized! ---"); logger.Log(string.Empty); - splashScreen?.InvokeClose(); } else { - logger.Log($"{Environment.NewLine}# Application terminated at {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}"); + logger.Info("--- Startup procedure aborted! ---"); } + + splashScreen?.InvokeClose(); } } } diff --git a/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ConfigurationOperationTests.cs b/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ConfigurationOperationTests.cs index e9230537..bdeab170 100644 --- a/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ConfigurationOperationTests.cs +++ b/SafeExamBrowser.Runtime.UnitTests/Behaviour/Operations/ConfigurationOperationTests.cs @@ -157,5 +157,38 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations controller.VerifySet(c => c.Settings = It.IsAny(), Times.Once); repository.Verify(r => r.LoadDefaults(), Times.Once); } + + [TestMethod] + public void MustAbortIfWishedByUser() + { + var location = Path.GetDirectoryName(GetType().Assembly.Location); + + info.SetupGet(r => r.ProgramDataFolder).Returns(location); + uiFactory.Setup(u => u.Show(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).Returns(MessageBoxResult.Yes); + + sut = new ConfigurationOperation(logger.Object, controller.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null) + { + SplashScreen = splashScreen.Object + }; + + sut.Perform(); + + Assert.IsTrue(sut.AbortStartup); + } + + [TestMethod] + public void MustNotAbortIfNotWishedByUser() + { + uiFactory.Setup(u => u.Show(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).Returns(MessageBoxResult.No); + + sut = new ConfigurationOperation(logger.Object, controller.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null) + { + SplashScreen = splashScreen.Object + }; + + sut.Perform(); + + Assert.IsFalse(sut.AbortStartup); + } } } diff --git a/SafeExamBrowser.Runtime/App.cs b/SafeExamBrowser.Runtime/App.cs index 02ce8690..e1ff1797 100644 --- a/SafeExamBrowser.Runtime/App.cs +++ b/SafeExamBrowser.Runtime/App.cs @@ -60,6 +60,7 @@ namespace SafeExamBrowser.Runtime base.OnStartup(e); instances.BuildObjectGraph(); + LogStartupInformation(); var success = instances.StartupController.TryInitializeApplication(instances.StartupOperations); @@ -76,6 +77,29 @@ namespace SafeExamBrowser.Runtime } } + protected override void OnExit(ExitEventArgs e) + { + instances.Logger?.Log($"{Environment.NewLine}# Application terminated at {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}"); + + base.OnExit(e); + } + + private void LogStartupInformation() + { + var runtimeInfo = instances.RuntimeInfo; + var logger = instances.Logger; + var titleLine = $"/* {runtimeInfo.ProgramTitle}, Version {runtimeInfo.ProgramVersion}{Environment.NewLine}"; + var copyrightLine = $"/* {runtimeInfo.ProgramCopyright}{Environment.NewLine}"; + var emptyLine = $"/* {Environment.NewLine}"; + var githubLine = $"/* Please visit https://github.com/SafeExamBrowser for more information."; + + logger.Log($"{titleLine}{copyrightLine}{emptyLine}{githubLine}"); + logger.Log(string.Empty); + logger.Log($"# Application started at {runtimeInfo.ApplicationStartTime.ToString("yyyy-MM-dd HH:mm:ss.fff")}"); + logger.Log($"# Running on {instances.SystemInfo.OperatingSystemInfo}"); + logger.Log(string.Empty); + } + private void MainWindow_Closing(object sender, CancelEventArgs e) { var operations = new Queue(instances.StartupOperations.Reverse()); diff --git a/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs b/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs index d74f8d29..85a8401b 100644 --- a/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs +++ b/SafeExamBrowser.Runtime/Behaviour/Operations/ConfigurationOperation.cs @@ -28,6 +28,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations private IUserInterfaceFactory uiFactory; private string[] commandLineArgs; + public bool AbortStartup { get; private set; } public ISplashScreen SplashScreen { private get; set; } public ConfigurationOperation( @@ -60,6 +61,13 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations { logger.Info($"Loading configuration from '{uri.AbsolutePath}'..."); settings = repository.Load(uri); + + if (settings.ConfigurationMode == ConfigurationMode.ConfigureClient && Abort()) + { + AbortStartup = true; + + return; + } } else { @@ -67,18 +75,6 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations settings = repository.LoadDefaults(); } - if (settings.ConfigurationMode == ConfigurationMode.ConfigureClient) - { - var message = text.Get(TextKey.MessageBox_ConfigureClientSuccess); - var title = text.Get(TextKey.MessageBox_ConfigureClientSuccessTitle); - var quitDialogResult = uiFactory.Show(message, title, MessageBoxAction.YesNo, MessageBoxIcon.Question); - - if (quitDialogResult == MessageBoxResult.Yes) - { - // TODO: Callback to terminate WPF application - } - } - controller.Settings = settings; } @@ -119,5 +115,24 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations return isValidUri; } + + private bool Abort() + { + var message = text.Get(TextKey.MessageBox_ConfigureClientSuccess); + var title = text.Get(TextKey.MessageBox_ConfigureClientSuccessTitle); + var quitDialogResult = uiFactory.Show(message, title, MessageBoxAction.YesNo, MessageBoxIcon.Question); + var abort = quitDialogResult == MessageBoxResult.Yes; + + if (abort) + { + logger.Info("The user chose to terminate the application after successful client configuration."); + } + else + { + logger.Info("The user chose to continue starting up the application after successful client configuration."); + } + + return abort; + } } } diff --git a/SafeExamBrowser.Runtime/Behaviour/Operations/RuntimeControllerOperation.cs b/SafeExamBrowser.Runtime/Behaviour/Operations/RuntimeControllerOperation.cs index 48527a0a..49c80c60 100644 --- a/SafeExamBrowser.Runtime/Behaviour/Operations/RuntimeControllerOperation.cs +++ b/SafeExamBrowser.Runtime/Behaviour/Operations/RuntimeControllerOperation.cs @@ -19,6 +19,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations private ILogger logger; private IRuntimeController controller; + public bool AbortStartup { get; private set; } public ISplashScreen SplashScreen { private get; set; } public RuntimeControllerOperation(IRuntimeController controller, ILogger logger) diff --git a/SafeExamBrowser.Runtime/CompositionRoot.cs b/SafeExamBrowser.Runtime/CompositionRoot.cs index d3ba7137..2535dab5 100644 --- a/SafeExamBrowser.Runtime/CompositionRoot.cs +++ b/SafeExamBrowser.Runtime/CompositionRoot.cs @@ -28,37 +28,41 @@ namespace SafeExamBrowser.Runtime { internal class CompositionRoot { + internal ILogger Logger { get; private set; } + internal RuntimeInfo RuntimeInfo { get; private set; } internal IShutdownController ShutdownController { get; private set; } internal IStartupController StartupController { get; private set; } + internal ISystemInfo SystemInfo { get; private set; } internal Queue StartupOperations { get; private set; } internal void BuildObjectGraph() { var args = Environment.GetCommandLineArgs(); - var logger = new Logger(); var nativeMethods = new NativeMethods(); - var runtimeInfo = new RuntimeInfo(); var settingsRepository = new SettingsRepository(); - var systemInfo = new SystemInfo(); var uiFactory = new UserInterfaceFactory(); - Initialize(runtimeInfo); - Initialize(logger, runtimeInfo); + Logger = new Logger(); + RuntimeInfo = new RuntimeInfo(); + SystemInfo = new SystemInfo(); - var text = new Text(logger); - var runtimeController = new RuntimeController(new ModuleLogger(logger, typeof(RuntimeController))); + InitializeRuntimeInfo(); + InitializeLogging(); - ShutdownController = new ShutdownController(logger, runtimeInfo, text, uiFactory); - StartupController = new StartupController(logger, runtimeInfo, systemInfo, text, uiFactory); + var text = new Text(Logger); + var runtimeController = new RuntimeController(new ModuleLogger(Logger, typeof(RuntimeController))); + + ShutdownController = new ShutdownController(Logger, RuntimeInfo, text, uiFactory); + StartupController = new StartupController(Logger, RuntimeInfo, SystemInfo, text, uiFactory); StartupOperations = new Queue(); - StartupOperations.Enqueue(new I18nOperation(logger, text)); - StartupOperations.Enqueue(new ConfigurationOperation(logger, runtimeController, runtimeInfo, settingsRepository, text, uiFactory, args)); + StartupOperations.Enqueue(new I18nOperation(Logger, text)); + StartupOperations.Enqueue(new ConfigurationOperation(Logger, runtimeController, RuntimeInfo, settingsRepository, text, uiFactory, args)); //StartupOperations.Enqueue(new KioskModeOperation()); - StartupOperations.Enqueue(new RuntimeControllerOperation(runtimeController, logger)); + StartupOperations.Enqueue(new RuntimeControllerOperation(runtimeController, Logger)); } - private void Initialize(RuntimeInfo runtimeInfo) + private void InitializeRuntimeInfo() { var appDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), nameof(SafeExamBrowser)); var executable = Assembly.GetEntryAssembly(); @@ -66,25 +70,25 @@ namespace SafeExamBrowser.Runtime var logFolder = Path.Combine(appDataFolder, "Logs"); var logFilePrefix = startTime.ToString("yyyy-MM-dd\\_HH\\hmm\\mss\\s"); - runtimeInfo.ApplicationStartTime = startTime; - runtimeInfo.AppDataFolder = appDataFolder; - runtimeInfo.BrowserCachePath = Path.Combine(appDataFolder, "Cache"); - runtimeInfo.BrowserLogFile = Path.Combine(logFolder, $"{logFilePrefix}_Browser.txt"); - runtimeInfo.ClientLogFile = Path.Combine(logFolder, $"{logFilePrefix}_Client.txt"); - runtimeInfo.DefaultSettingsFileName = "SebClientSettings.seb"; - runtimeInfo.ProgramCopyright = executable.GetCustomAttribute().Copyright; - runtimeInfo.ProgramDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), nameof(SafeExamBrowser)); - runtimeInfo.ProgramTitle = executable.GetCustomAttribute().Title; - runtimeInfo.ProgramVersion = executable.GetCustomAttribute().InformationalVersion; - runtimeInfo.RuntimeLogFile = Path.Combine(logFolder, $"{logFilePrefix}_Runtime.txt"); + RuntimeInfo.ApplicationStartTime = startTime; + RuntimeInfo.AppDataFolder = appDataFolder; + RuntimeInfo.BrowserCachePath = Path.Combine(appDataFolder, "Cache"); + RuntimeInfo.BrowserLogFile = Path.Combine(logFolder, $"{logFilePrefix}_Browser.txt"); + RuntimeInfo.ClientLogFile = Path.Combine(logFolder, $"{logFilePrefix}_Client.txt"); + RuntimeInfo.DefaultSettingsFileName = "SebClientSettings.seb"; + RuntimeInfo.ProgramCopyright = executable.GetCustomAttribute().Copyright; + RuntimeInfo.ProgramDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), nameof(SafeExamBrowser)); + RuntimeInfo.ProgramTitle = executable.GetCustomAttribute().Title; + RuntimeInfo.ProgramVersion = executable.GetCustomAttribute().InformationalVersion; + RuntimeInfo.RuntimeLogFile = Path.Combine(logFolder, $"{logFilePrefix}_Runtime.txt"); } - private void Initialize(ILogger logger, IRuntimeInfo runtimeInfo) + private void InitializeLogging() { - var logFileWriter = new LogFileWriter(new DefaultLogFormatter(), runtimeInfo.RuntimeLogFile); + var logFileWriter = new LogFileWriter(new DefaultLogFormatter(), RuntimeInfo.RuntimeLogFile); logFileWriter.Initialize(); - logger.Subscribe(logFileWriter); + Logger.Subscribe(logFileWriter); } } }