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);
}
}
}