SEBWIN-219: Finished basic version of configuration operation.
This commit is contained in:
parent
80be746860
commit
f321496815
20 changed files with 229 additions and 65 deletions
|
@ -23,6 +23,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
private ITaskbar taskbar;
|
private ITaskbar taskbar;
|
||||||
private IUserInterfaceFactory uiFactory;
|
private IUserInterfaceFactory uiFactory;
|
||||||
|
|
||||||
|
public bool AbortStartup { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public ISplashScreen SplashScreen { private get; set; }
|
||||||
|
|
||||||
public BrowserOperation(
|
public BrowserOperation(
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private IClientController controller;
|
private IClientController controller;
|
||||||
|
|
||||||
|
public bool AbortStartup { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public ISplashScreen SplashScreen { private get; set; }
|
||||||
|
|
||||||
public ClientControllerOperation(IClientController controller, ILogger logger)
|
public ClientControllerOperation(IClientController controller, ILogger logger)
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private INativeMethods nativeMethods;
|
private INativeMethods nativeMethods;
|
||||||
|
|
||||||
|
public bool AbortStartup { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public ISplashScreen SplashScreen { private get; set; }
|
||||||
|
|
||||||
public ClipboardOperation(ILogger logger, INativeMethods nativeMethods)
|
public ClipboardOperation(ILogger logger, INativeMethods nativeMethods)
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private ITaskbar taskbar;
|
private ITaskbar taskbar;
|
||||||
|
|
||||||
|
public bool AbortStartup { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public ISplashScreen SplashScreen { private get; set; }
|
||||||
|
|
||||||
public DisplayMonitorOperation(IDisplayMonitor displayMonitor, ILogger logger, ITaskbar taskbar)
|
public DisplayMonitorOperation(IDisplayMonitor displayMonitor, ILogger logger, ITaskbar taskbar)
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private INativeMethods nativeMethods;
|
private INativeMethods nativeMethods;
|
||||||
|
|
||||||
|
public bool AbortStartup { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public ISplashScreen SplashScreen { private get; set; }
|
||||||
|
|
||||||
public KeyboardInterceptorOperation(
|
public KeyboardInterceptorOperation(
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
private IMouseInterceptor mouseInterceptor;
|
private IMouseInterceptor mouseInterceptor;
|
||||||
private INativeMethods nativeMethods;
|
private INativeMethods nativeMethods;
|
||||||
|
|
||||||
|
public bool AbortStartup { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public ISplashScreen SplashScreen { private get; set; }
|
||||||
|
|
||||||
public MouseInterceptorOperation(
|
public MouseInterceptorOperation(
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private IProcessMonitor processMonitor;
|
private IProcessMonitor processMonitor;
|
||||||
|
|
||||||
|
public bool AbortStartup { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public ISplashScreen SplashScreen { private get; set; }
|
||||||
|
|
||||||
public ProcessMonitorOperation(ILogger logger, IProcessMonitor processMonitor)
|
public ProcessMonitorOperation(ILogger logger, IProcessMonitor processMonitor)
|
||||||
|
|
|
@ -31,6 +31,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
private IUserInterfaceFactory uiFactory;
|
private IUserInterfaceFactory uiFactory;
|
||||||
private IText text;
|
private IText text;
|
||||||
|
|
||||||
|
public bool AbortStartup { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public ISplashScreen SplashScreen { private get; set; }
|
||||||
|
|
||||||
public TaskbarOperation(
|
public TaskbarOperation(
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private IWindowMonitor windowMonitor;
|
private IWindowMonitor windowMonitor;
|
||||||
|
|
||||||
|
public bool AbortStartup { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public ISplashScreen SplashScreen { private get; set; }
|
||||||
|
|
||||||
public WindowMonitorOperation(ILogger logger, IWindowMonitor windowMonitor)
|
public WindowMonitorOperation(ILogger logger, IWindowMonitor windowMonitor)
|
||||||
|
|
|
@ -12,6 +12,11 @@ namespace SafeExamBrowser.Contracts.Behaviour
|
||||||
{
|
{
|
||||||
public interface IOperation
|
public interface IOperation
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the startup procedure to which this operation belongs should be aborted.
|
||||||
|
/// </summary>
|
||||||
|
bool AbortStartup { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The splash screen to be used to show status information to the user.
|
/// The splash screen to be used to show status information to the user.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -57,8 +57,11 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
|
||||||
sut.FinalizeApplication(operations);
|
sut.FinalizeApplication(operations);
|
||||||
|
|
||||||
operationA.Verify(o => o.Revert(), Times.Once);
|
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.Revert(), Times.Once);
|
||||||
|
operationB.Verify(o => o.Perform(), Times.Never);
|
||||||
operationC.Verify(o => o.Revert(), Times.Once);
|
operationC.Verify(o => o.Revert(), Times.Once);
|
||||||
|
operationC.Verify(o => o.Perform(), Times.Never);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -108,6 +111,27 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
|
||||||
operationC.Verify(o => o.Revert(), Times.Once);
|
operationC.Verify(o => o.Revert(), Times.Once);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MustNotEvaluateAbortFlag()
|
||||||
|
{
|
||||||
|
var operationA = new Mock<IOperation>();
|
||||||
|
var operationB = new Mock<IOperation>();
|
||||||
|
var operationC = new Mock<IOperation>();
|
||||||
|
var operations = new Queue<IOperation>();
|
||||||
|
|
||||||
|
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]
|
[TestMethod]
|
||||||
public void MustNotFailWithEmptyQueue()
|
public void MustNotFailWithEmptyQueue()
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,7 +12,6 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
using Moq;
|
using Moq;
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour;
|
||||||
using SafeExamBrowser.Contracts.Configuration;
|
using SafeExamBrowser.Contracts.Configuration;
|
||||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
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);
|
sut = new StartupController(loggerMock.Object, runtimeInfoMock.Object, systemInfoMock.Object, textMock.Object, uiFactoryMock.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MustCorrectlyAbortProcess()
|
||||||
|
{
|
||||||
|
var operationA = new Mock<IOperation>();
|
||||||
|
var operationB = new Mock<IOperation>();
|
||||||
|
var operationC = new Mock<IOperation>();
|
||||||
|
var operations = new Queue<IOperation>();
|
||||||
|
|
||||||
|
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]
|
[TestMethod]
|
||||||
public void MustPerformOperations()
|
public void MustPerformOperations()
|
||||||
{
|
{
|
||||||
|
@ -60,8 +85,11 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
|
||||||
var result = sut.TryInitializeApplication(operations);
|
var result = sut.TryInitializeApplication(operations);
|
||||||
|
|
||||||
operationA.Verify(o => o.Perform(), Times.Once);
|
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.Perform(), Times.Once);
|
||||||
|
operationB.Verify(o => o.Revert(), Times.Never);
|
||||||
operationC.Verify(o => o.Perform(), Times.Once);
|
operationC.Verify(o => o.Perform(), Times.Once);
|
||||||
|
operationC.Verify(o => o.Revert(), Times.Never);
|
||||||
|
|
||||||
Assert.IsTrue(result);
|
Assert.IsTrue(result);
|
||||||
}
|
}
|
||||||
|
@ -183,5 +211,13 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
|
||||||
|
|
||||||
Assert.IsTrue(result);
|
Assert.IsTrue(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MustNotFailInCaseOfUnexpectedError()
|
||||||
|
{
|
||||||
|
uiFactoryMock.Setup(l => l.CreateSplashScreen(It.IsAny<IRuntimeInfo>(), It.IsAny<IText>())).Throws(new Exception());
|
||||||
|
sut.TryInitializeApplication(new Queue<IOperation>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private IText text;
|
private IText text;
|
||||||
|
|
||||||
|
public bool AbortStartup { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public ISplashScreen SplashScreen { private get; set; }
|
||||||
|
|
||||||
public I18nOperation(ILogger logger, IText text)
|
public I18nOperation(ILogger logger, IText text)
|
||||||
|
|
|
@ -10,7 +10,6 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour;
|
||||||
using SafeExamBrowser.Contracts.Configuration;
|
using SafeExamBrowser.Contracts.Configuration;
|
||||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
using SafeExamBrowser.Contracts.UserInterface;
|
||||||
|
@ -88,8 +87,11 @@ namespace SafeExamBrowser.Core.Behaviour
|
||||||
{
|
{
|
||||||
logger.Info("--- Application successfully finalized! ---");
|
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();
|
splashScreen?.InvokeClose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour;
|
||||||
using SafeExamBrowser.Contracts.Configuration;
|
using SafeExamBrowser.Contracts.Configuration;
|
||||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
using SafeExamBrowser.Contracts.UserInterface;
|
||||||
|
@ -40,35 +39,56 @@ namespace SafeExamBrowser.Core.Behaviour
|
||||||
|
|
||||||
public bool TryInitializeApplication(Queue<IOperation> operations)
|
public bool TryInitializeApplication(Queue<IOperation> operations)
|
||||||
{
|
{
|
||||||
|
var success = false;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Initialize(operations.Count);
|
Initialize(operations.Count);
|
||||||
Perform(operations);
|
success = Perform(operations);
|
||||||
Finish();
|
|
||||||
|
|
||||||
return true;
|
if (!success)
|
||||||
|
{
|
||||||
|
RevertOperations();
|
||||||
|
}
|
||||||
|
|
||||||
|
Finish(success);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LogAndShowException(e);
|
LogAndShowException(e);
|
||||||
RevertOperations();
|
|
||||||
Finish(false);
|
Finish(false);
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Perform(Queue<IOperation> operations)
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool Perform(Queue<IOperation> operations)
|
||||||
{
|
{
|
||||||
foreach (var operation in operations)
|
foreach (var operation in operations)
|
||||||
{
|
{
|
||||||
stack.Push(operation);
|
stack.Push(operation);
|
||||||
|
|
||||||
operation.SplashScreen = splashScreen;
|
operation.SplashScreen = splashScreen;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
operation.Perform();
|
operation.Perform();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
LogAndShowException(e);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (operation.AbortStartup)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
splashScreen.Progress();
|
splashScreen.Progress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RevertOperations()
|
private void RevertOperations()
|
||||||
|
@ -92,17 +112,6 @@ namespace SafeExamBrowser.Core.Behaviour
|
||||||
|
|
||||||
private void Initialize(int operationCount)
|
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 ---");
|
logger.Info("--- Initiating startup procedure ---");
|
||||||
|
|
||||||
splashScreen = uiFactory.CreateSplashScreen(runtimeInfo, text);
|
splashScreen = uiFactory.CreateSplashScreen(runtimeInfo, text);
|
||||||
|
@ -124,12 +133,13 @@ namespace SafeExamBrowser.Core.Behaviour
|
||||||
{
|
{
|
||||||
logger.Info("--- Application successfully initialized! ---");
|
logger.Info("--- Application successfully initialized! ---");
|
||||||
logger.Log(string.Empty);
|
logger.Log(string.Empty);
|
||||||
splashScreen?.InvokeClose();
|
|
||||||
}
|
}
|
||||||
else
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -157,5 +157,38 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
||||||
controller.VerifySet(c => c.Settings = It.IsAny<ISettings>(), Times.Once);
|
controller.VerifySet(c => c.Settings = It.IsAny<ISettings>(), Times.Once);
|
||||||
repository.Verify(r => r.LoadDefaults(), 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<string>(), It.IsAny<string>(), It.IsAny<MessageBoxAction>(), It.IsAny<MessageBoxIcon>())).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<string>(), It.IsAny<string>(), It.IsAny<MessageBoxAction>(), It.IsAny<MessageBoxIcon>())).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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,7 @@ namespace SafeExamBrowser.Runtime
|
||||||
base.OnStartup(e);
|
base.OnStartup(e);
|
||||||
|
|
||||||
instances.BuildObjectGraph();
|
instances.BuildObjectGraph();
|
||||||
|
LogStartupInformation();
|
||||||
|
|
||||||
var success = instances.StartupController.TryInitializeApplication(instances.StartupOperations);
|
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)
|
private void MainWindow_Closing(object sender, CancelEventArgs e)
|
||||||
{
|
{
|
||||||
var operations = new Queue<IOperation>(instances.StartupOperations.Reverse());
|
var operations = new Queue<IOperation>(instances.StartupOperations.Reverse());
|
||||||
|
|
|
@ -28,6 +28,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
private IUserInterfaceFactory uiFactory;
|
private IUserInterfaceFactory uiFactory;
|
||||||
private string[] commandLineArgs;
|
private string[] commandLineArgs;
|
||||||
|
|
||||||
|
public bool AbortStartup { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public ISplashScreen SplashScreen { private get; set; }
|
||||||
|
|
||||||
public ConfigurationOperation(
|
public ConfigurationOperation(
|
||||||
|
@ -60,6 +61,13 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
{
|
{
|
||||||
logger.Info($"Loading configuration from '{uri.AbsolutePath}'...");
|
logger.Info($"Loading configuration from '{uri.AbsolutePath}'...");
|
||||||
settings = repository.Load(uri);
|
settings = repository.Load(uri);
|
||||||
|
|
||||||
|
if (settings.ConfigurationMode == ConfigurationMode.ConfigureClient && Abort())
|
||||||
|
{
|
||||||
|
AbortStartup = true;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -67,18 +75,6 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
settings = repository.LoadDefaults();
|
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;
|
controller.Settings = settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,5 +115,24 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
|
|
||||||
return isValidUri;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private IRuntimeController controller;
|
private IRuntimeController controller;
|
||||||
|
|
||||||
|
public bool AbortStartup { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public ISplashScreen SplashScreen { private get; set; }
|
||||||
|
|
||||||
public RuntimeControllerOperation(IRuntimeController controller, ILogger logger)
|
public RuntimeControllerOperation(IRuntimeController controller, ILogger logger)
|
||||||
|
|
|
@ -28,37 +28,41 @@ namespace SafeExamBrowser.Runtime
|
||||||
{
|
{
|
||||||
internal class CompositionRoot
|
internal class CompositionRoot
|
||||||
{
|
{
|
||||||
|
internal ILogger Logger { get; private set; }
|
||||||
|
internal RuntimeInfo RuntimeInfo { get; private set; }
|
||||||
internal IShutdownController ShutdownController { get; private set; }
|
internal IShutdownController ShutdownController { get; private set; }
|
||||||
internal IStartupController StartupController { get; private set; }
|
internal IStartupController StartupController { get; private set; }
|
||||||
|
internal ISystemInfo SystemInfo { get; private set; }
|
||||||
internal Queue<IOperation> StartupOperations { get; private set; }
|
internal Queue<IOperation> StartupOperations { get; private set; }
|
||||||
|
|
||||||
internal void BuildObjectGraph()
|
internal void BuildObjectGraph()
|
||||||
{
|
{
|
||||||
var args = Environment.GetCommandLineArgs();
|
var args = Environment.GetCommandLineArgs();
|
||||||
var logger = new Logger();
|
|
||||||
var nativeMethods = new NativeMethods();
|
var nativeMethods = new NativeMethods();
|
||||||
var runtimeInfo = new RuntimeInfo();
|
|
||||||
var settingsRepository = new SettingsRepository();
|
var settingsRepository = new SettingsRepository();
|
||||||
var systemInfo = new SystemInfo();
|
|
||||||
var uiFactory = new UserInterfaceFactory();
|
var uiFactory = new UserInterfaceFactory();
|
||||||
|
|
||||||
Initialize(runtimeInfo);
|
Logger = new Logger();
|
||||||
Initialize(logger, runtimeInfo);
|
RuntimeInfo = new RuntimeInfo();
|
||||||
|
SystemInfo = new SystemInfo();
|
||||||
|
|
||||||
var text = new Text(logger);
|
InitializeRuntimeInfo();
|
||||||
var runtimeController = new RuntimeController(new ModuleLogger(logger, typeof(RuntimeController)));
|
InitializeLogging();
|
||||||
|
|
||||||
ShutdownController = new ShutdownController(logger, runtimeInfo, text, uiFactory);
|
var text = new Text(Logger);
|
||||||
StartupController = new StartupController(logger, runtimeInfo, systemInfo, text, uiFactory);
|
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<IOperation>();
|
StartupOperations = new Queue<IOperation>();
|
||||||
StartupOperations.Enqueue(new I18nOperation(logger, text));
|
StartupOperations.Enqueue(new I18nOperation(Logger, text));
|
||||||
StartupOperations.Enqueue(new ConfigurationOperation(logger, runtimeController, runtimeInfo, settingsRepository, text, uiFactory, args));
|
StartupOperations.Enqueue(new ConfigurationOperation(Logger, runtimeController, RuntimeInfo, settingsRepository, text, uiFactory, args));
|
||||||
//StartupOperations.Enqueue(new KioskModeOperation());
|
//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 appDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), nameof(SafeExamBrowser));
|
||||||
var executable = Assembly.GetEntryAssembly();
|
var executable = Assembly.GetEntryAssembly();
|
||||||
|
@ -66,25 +70,25 @@ namespace SafeExamBrowser.Runtime
|
||||||
var logFolder = Path.Combine(appDataFolder, "Logs");
|
var logFolder = Path.Combine(appDataFolder, "Logs");
|
||||||
var logFilePrefix = startTime.ToString("yyyy-MM-dd\\_HH\\hmm\\mss\\s");
|
var logFilePrefix = startTime.ToString("yyyy-MM-dd\\_HH\\hmm\\mss\\s");
|
||||||
|
|
||||||
runtimeInfo.ApplicationStartTime = startTime;
|
RuntimeInfo.ApplicationStartTime = startTime;
|
||||||
runtimeInfo.AppDataFolder = appDataFolder;
|
RuntimeInfo.AppDataFolder = appDataFolder;
|
||||||
runtimeInfo.BrowserCachePath = Path.Combine(appDataFolder, "Cache");
|
RuntimeInfo.BrowserCachePath = Path.Combine(appDataFolder, "Cache");
|
||||||
runtimeInfo.BrowserLogFile = Path.Combine(logFolder, $"{logFilePrefix}_Browser.txt");
|
RuntimeInfo.BrowserLogFile = Path.Combine(logFolder, $"{logFilePrefix}_Browser.txt");
|
||||||
runtimeInfo.ClientLogFile = Path.Combine(logFolder, $"{logFilePrefix}_Client.txt");
|
RuntimeInfo.ClientLogFile = Path.Combine(logFolder, $"{logFilePrefix}_Client.txt");
|
||||||
runtimeInfo.DefaultSettingsFileName = "SebClientSettings.seb";
|
RuntimeInfo.DefaultSettingsFileName = "SebClientSettings.seb";
|
||||||
runtimeInfo.ProgramCopyright = executable.GetCustomAttribute<AssemblyCopyrightAttribute>().Copyright;
|
RuntimeInfo.ProgramCopyright = executable.GetCustomAttribute<AssemblyCopyrightAttribute>().Copyright;
|
||||||
runtimeInfo.ProgramDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), nameof(SafeExamBrowser));
|
RuntimeInfo.ProgramDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), nameof(SafeExamBrowser));
|
||||||
runtimeInfo.ProgramTitle = executable.GetCustomAttribute<AssemblyTitleAttribute>().Title;
|
RuntimeInfo.ProgramTitle = executable.GetCustomAttribute<AssemblyTitleAttribute>().Title;
|
||||||
runtimeInfo.ProgramVersion = executable.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;
|
RuntimeInfo.ProgramVersion = executable.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;
|
||||||
runtimeInfo.RuntimeLogFile = Path.Combine(logFolder, $"{logFilePrefix}_Runtime.txt");
|
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();
|
logFileWriter.Initialize();
|
||||||
logger.Subscribe(logFileWriter);
|
Logger.Subscribe(logFileWriter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue