SEBWIN-219: Changed and simplified implementation of operation mechanism to allow reconfiguration (i.e. repeating operations).
This commit is contained in:
parent
18b8f66300
commit
196836b7eb
32 changed files with 461 additions and 462 deletions
|
@ -12,7 +12,7 @@ using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Client
|
namespace SafeExamBrowser.Client
|
||||||
{
|
{
|
||||||
|
@ -61,18 +61,18 @@ namespace SafeExamBrowser.Client
|
||||||
|
|
||||||
instances.BuildObjectGraph();
|
instances.BuildObjectGraph();
|
||||||
|
|
||||||
var success = instances.StartupController.TryInitializeApplication(instances.StartupOperations);
|
//var success = instances.StartupController.TryInitializeApplication(instances.StartupOperations);
|
||||||
|
|
||||||
if (success)
|
//if (success)
|
||||||
{
|
//{
|
||||||
MainWindow = instances.Taskbar;
|
// MainWindow = instances.Taskbar;
|
||||||
MainWindow.Closing += MainWindow_Closing;
|
// MainWindow.Closing += MainWindow_Closing;
|
||||||
MainWindow.Show();
|
// MainWindow.Show();
|
||||||
}
|
//}
|
||||||
else
|
//else
|
||||||
{
|
//{
|
||||||
Shutdown();
|
// Shutdown();
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void MainWindow_Closing(object sender, CancelEventArgs e)
|
private void MainWindow_Closing(object sender, CancelEventArgs e)
|
||||||
|
@ -80,7 +80,7 @@ namespace SafeExamBrowser.Client
|
||||||
var operations = new Queue<IOperation>(instances.StartupOperations.Reverse());
|
var operations = new Queue<IOperation>(instances.StartupOperations.Reverse());
|
||||||
|
|
||||||
MainWindow.Hide();
|
MainWindow.Hide();
|
||||||
instances.ShutdownController.FinalizeApplication(operations);
|
//instances.ShutdownController.FinalizeApplication(operations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour;
|
||||||
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.Configuration;
|
using SafeExamBrowser.Contracts.Configuration;
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
|
@ -23,7 +24,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 bool Abort { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public ISplashScreen SplashScreen { private get; set; }
|
||||||
|
|
||||||
public BrowserOperation(
|
public BrowserOperation(
|
||||||
|
@ -53,6 +54,11 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
taskbar.AddApplication(browserButton);
|
taskbar.AddApplication(browserButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Repeat()
|
||||||
|
{
|
||||||
|
// Nothing to do here...
|
||||||
|
}
|
||||||
|
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
logger.Info("Terminating browser...");
|
logger.Info("Terminating browser...");
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour;
|
||||||
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
using SafeExamBrowser.Contracts.UserInterface;
|
||||||
|
@ -18,7 +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 bool Abort { 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)
|
||||||
|
@ -35,6 +36,11 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
controller.Start();
|
controller.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Repeat()
|
||||||
|
{
|
||||||
|
// Nothing to do here...
|
||||||
|
}
|
||||||
|
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
logger.Info("Stopping event handling...");
|
logger.Info("Stopping event handling...");
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
using SafeExamBrowser.Contracts.UserInterface;
|
||||||
|
@ -19,7 +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 bool Abort { 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)
|
||||||
|
@ -33,6 +33,11 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
EmptyClipboard();
|
EmptyClipboard();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Repeat()
|
||||||
|
{
|
||||||
|
// Nothing to do here...
|
||||||
|
}
|
||||||
|
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
EmptyClipboard();
|
EmptyClipboard();
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.Monitoring;
|
using SafeExamBrowser.Contracts.Monitoring;
|
||||||
|
@ -21,7 +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 bool Abort { 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)
|
||||||
|
@ -41,6 +41,11 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
displayMonitor.StartMonitoringDisplayChanges();
|
displayMonitor.StartMonitoringDisplayChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Repeat()
|
||||||
|
{
|
||||||
|
// Nothing to do here...
|
||||||
|
}
|
||||||
|
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
logger.Info("Restoring working area...");
|
logger.Info("Restoring working area...");
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.Monitoring;
|
using SafeExamBrowser.Contracts.Monitoring;
|
||||||
|
@ -21,7 +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 bool Abort { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public ISplashScreen SplashScreen { private get; set; }
|
||||||
|
|
||||||
public KeyboardInterceptorOperation(
|
public KeyboardInterceptorOperation(
|
||||||
|
@ -40,7 +40,11 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
SplashScreen.UpdateText(TextKey.SplashScreen_StartKeyboardInterception);
|
SplashScreen.UpdateText(TextKey.SplashScreen_StartKeyboardInterception);
|
||||||
|
|
||||||
nativeMethods.RegisterKeyboardHook(keyboardInterceptor);
|
nativeMethods.RegisterKeyboardHook(keyboardInterceptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Repeat()
|
||||||
|
{
|
||||||
|
// Nothing to do here...
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Revert()
|
public void Revert()
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.Monitoring;
|
using SafeExamBrowser.Contracts.Monitoring;
|
||||||
|
@ -21,7 +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 bool Abort { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public ISplashScreen SplashScreen { private get; set; }
|
||||||
|
|
||||||
public MouseInterceptorOperation(
|
public MouseInterceptorOperation(
|
||||||
|
@ -42,6 +42,11 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
nativeMethods.RegisterMouseHook(mouseInterceptor);
|
nativeMethods.RegisterMouseHook(mouseInterceptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Repeat()
|
||||||
|
{
|
||||||
|
// Nothing to do here...
|
||||||
|
}
|
||||||
|
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
logger.Info("Stopping mouse interception...");
|
logger.Info("Stopping mouse interception...");
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.Monitoring;
|
using SafeExamBrowser.Contracts.Monitoring;
|
||||||
|
@ -19,7 +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 bool Abort { 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)
|
||||||
|
@ -41,6 +41,11 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Repeat()
|
||||||
|
{
|
||||||
|
// Nothing to do here...
|
||||||
|
}
|
||||||
|
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
logger.Info("Stopping process monitoring...");
|
logger.Info("Stopping process monitoring...");
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
using SafeExamBrowser.Client.Notifications;
|
using SafeExamBrowser.Client.Notifications;
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour;
|
||||||
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.Configuration;
|
using SafeExamBrowser.Contracts.Configuration;
|
||||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
|
@ -31,7 +32,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 bool Abort { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public ISplashScreen SplashScreen { private get; set; }
|
||||||
|
|
||||||
public TaskbarOperation(
|
public TaskbarOperation(
|
||||||
|
@ -82,6 +83,11 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Repeat()
|
||||||
|
{
|
||||||
|
// Nothing to do here...
|
||||||
|
}
|
||||||
|
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
logger.Info("Terminating taskbar...");
|
logger.Info("Terminating taskbar...");
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.Monitoring;
|
using SafeExamBrowser.Contracts.Monitoring;
|
||||||
|
@ -19,7 +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 bool Abort { 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)
|
||||||
|
@ -37,6 +37,11 @@ namespace SafeExamBrowser.Client.Behaviour.Operations
|
||||||
windowMonitor.StartMonitoringWindows();
|
windowMonitor.StartMonitoringWindows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Repeat()
|
||||||
|
{
|
||||||
|
// Nothing to do here...
|
||||||
|
}
|
||||||
|
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
logger.Info("Stopping window monitoring...");
|
logger.Info("Stopping window monitoring...");
|
||||||
|
|
|
@ -11,6 +11,7 @@ using SafeExamBrowser.Browser;
|
||||||
using SafeExamBrowser.Configuration;
|
using SafeExamBrowser.Configuration;
|
||||||
using SafeExamBrowser.Configuration.Settings;
|
using SafeExamBrowser.Configuration.Settings;
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour;
|
||||||
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.Configuration;
|
using SafeExamBrowser.Contracts.Configuration;
|
||||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
|
@ -47,8 +48,8 @@ namespace SafeExamBrowser.Client
|
||||||
private IUserInterfaceFactory uiFactory;
|
private IUserInterfaceFactory uiFactory;
|
||||||
private IWindowMonitor windowMonitor;
|
private IWindowMonitor windowMonitor;
|
||||||
|
|
||||||
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 Queue<IOperation> StartupOperations { get; private set; }
|
internal Queue<IOperation> StartupOperations { get; private set; }
|
||||||
internal Taskbar Taskbar { get; private set; }
|
internal Taskbar Taskbar { get; private set; }
|
||||||
|
|
||||||
|
|
|
@ -6,18 +6,21 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Contracts.Behaviour
|
namespace SafeExamBrowser.Contracts.Behaviour
|
||||||
{
|
{
|
||||||
public interface IRuntimeController : IStartupController
|
public interface IRuntimeController
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reverts any changes performed during the startup or runtime and releases all used resources.
|
/// Reverts any changes, releases all used resources and terminates the runtime.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void FinalizeApplication();
|
void Terminate();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new session and starts performing the runtime logic / event handling.
|
/// Tries to start the runtime. Returns <c>true</c> if successful, otherwise <c>false</c>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void StartSession();
|
bool TryStart(Queue<IOperation> operations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.Contracts.Behaviour
|
|
||||||
{
|
|
||||||
public interface IShutdownController
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Reverts any changes performed during the startup or runtime and releases all used resources.
|
|
||||||
/// </summary>
|
|
||||||
void FinalizeApplication(Queue<IOperation> operations);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.Contracts.Behaviour
|
|
||||||
{
|
|
||||||
public interface IStartupController
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Tries to initialize the application according to the given queue of operations.
|
|
||||||
/// Returns <c>true</c> if the initialization was successful, <c>false</c> otherwise.
|
|
||||||
/// </summary>
|
|
||||||
bool TryInitializeApplication(Queue<IOperation> operations);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,14 +8,14 @@
|
||||||
|
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
using SafeExamBrowser.Contracts.UserInterface;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Contracts.Behaviour
|
namespace SafeExamBrowser.Contracts.Behaviour.Operations
|
||||||
{
|
{
|
||||||
public interface IOperation
|
public interface IOperation
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the startup procedure to which this operation belongs should be aborted.
|
/// Determines whether the procedure to which this operation belongs should be aborted.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
bool AbortStartup { get; }
|
bool Abort { 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.
|
||||||
|
@ -27,6 +27,11 @@ namespace SafeExamBrowser.Contracts.Behaviour
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Perform();
|
void Perform();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Repeats the operation.
|
||||||
|
/// </summary>
|
||||||
|
void Repeat();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reverts all changes which were made when performing the operation.
|
/// Reverts all changes which were made when performing the operation.
|
||||||
/// </summary>
|
/// </summary>
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SafeExamBrowser.Contracts.Behaviour.Operations
|
||||||
|
{
|
||||||
|
public interface IOperationSequence
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Tries to perform the given sequence of operations. Returns <c>true</c> if the procedure was successful, <c>false</c> otherwise.
|
||||||
|
/// </summary>
|
||||||
|
bool TryPerform(Queue<IOperation> operations);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tries to repeat all operations of this sequence. Returns <c>true</c> if the procedure was successful, <c>false</c> otherwise.
|
||||||
|
/// </summary>
|
||||||
|
bool TryRepeat();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tries to revert all operations of this sequence. Returns <c>true</c> if the procedure was successful, <c>false</c> otherwise.
|
||||||
|
/// </summary>
|
||||||
|
bool TryRevert();
|
||||||
|
}
|
||||||
|
}
|
|
@ -55,6 +55,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Behaviour\IApplicationController.cs" />
|
<Compile Include="Behaviour\IApplicationController.cs" />
|
||||||
<Compile Include="Behaviour\IRuntimeController.cs" />
|
<Compile Include="Behaviour\IRuntimeController.cs" />
|
||||||
|
<Compile Include="Behaviour\Operations\IOperationSequence.cs" />
|
||||||
<Compile Include="Communication\ICommunication.cs" />
|
<Compile Include="Communication\ICommunication.cs" />
|
||||||
<Compile Include="Communication\IClientProxy.cs" />
|
<Compile Include="Communication\IClientProxy.cs" />
|
||||||
<Compile Include="Communication\IRuntimeProxy.cs" />
|
<Compile Include="Communication\IRuntimeProxy.cs" />
|
||||||
|
@ -65,7 +66,7 @@
|
||||||
<Compile Include="Configuration\IRuntimeInfo.cs" />
|
<Compile Include="Configuration\IRuntimeInfo.cs" />
|
||||||
<Compile Include="Configuration\Settings\ConfigurationMode.cs" />
|
<Compile Include="Configuration\Settings\ConfigurationMode.cs" />
|
||||||
<Compile Include="Behaviour\INotificationController.cs" />
|
<Compile Include="Behaviour\INotificationController.cs" />
|
||||||
<Compile Include="Behaviour\IOperation.cs" />
|
<Compile Include="Behaviour\Operations\IOperation.cs" />
|
||||||
<Compile Include="Behaviour\IClientController.cs" />
|
<Compile Include="Behaviour\IClientController.cs" />
|
||||||
<Compile Include="Configuration\IIconResource.cs" />
|
<Compile Include="Configuration\IIconResource.cs" />
|
||||||
<Compile Include="Configuration\IApplicationInfo.cs" />
|
<Compile Include="Configuration\IApplicationInfo.cs" />
|
||||||
|
@ -77,8 +78,6 @@
|
||||||
<Compile Include="Configuration\Settings\IKeyboardSettings.cs" />
|
<Compile Include="Configuration\Settings\IKeyboardSettings.cs" />
|
||||||
<Compile Include="Configuration\Settings\IMouseSettings.cs" />
|
<Compile Include="Configuration\Settings\IMouseSettings.cs" />
|
||||||
<Compile Include="Configuration\Settings\ISettings.cs" />
|
<Compile Include="Configuration\Settings\ISettings.cs" />
|
||||||
<Compile Include="Behaviour\IShutdownController.cs" />
|
|
||||||
<Compile Include="Behaviour\IStartupController.cs" />
|
|
||||||
<Compile Include="Configuration\Settings\ISettingsRepository.cs" />
|
<Compile Include="Configuration\Settings\ISettingsRepository.cs" />
|
||||||
<Compile Include="Configuration\Settings\ITaskbarSettings.cs" />
|
<Compile Include="Configuration\Settings\ITaskbarSettings.cs" />
|
||||||
<Compile Include="Configuration\Settings\KioskMode.cs" />
|
<Compile Include="Configuration\Settings\KioskMode.cs" />
|
||||||
|
|
|
@ -10,40 +10,39 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
using Moq;
|
using Moq;
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.Configuration;
|
using SafeExamBrowser.Contracts.Configuration;
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
using SafeExamBrowser.Contracts.UserInterface;
|
||||||
using SafeExamBrowser.Core.Behaviour;
|
using SafeExamBrowser.Core.Behaviour.Operations;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Core.UnitTests.Behaviour
|
namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
|
||||||
{
|
{
|
||||||
[TestClass]
|
[TestClass]
|
||||||
public class StartupControllerTests
|
public class OperationSequenceTests
|
||||||
{
|
{
|
||||||
private Mock<ILogger> loggerMock;
|
private Mock<ILogger> loggerMock;
|
||||||
private Mock<IRuntimeInfo> runtimeInfoMock;
|
private Mock<IRuntimeInfo> runtimeInfoMock;
|
||||||
private Mock<ISystemInfo> systemInfoMock;
|
|
||||||
private Mock<IText> textMock;
|
private Mock<IText> textMock;
|
||||||
private Mock<IUserInterfaceFactory> uiFactoryMock;
|
private Mock<IUserInterfaceFactory> uiFactoryMock;
|
||||||
|
|
||||||
private IStartupController sut;
|
private IOperationSequence sut;
|
||||||
|
|
||||||
[TestInitialize]
|
[TestInitialize]
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
{
|
{
|
||||||
loggerMock = new Mock<ILogger>();
|
loggerMock = new Mock<ILogger>();
|
||||||
runtimeInfoMock = new Mock<IRuntimeInfo>();
|
runtimeInfoMock = new Mock<IRuntimeInfo>();
|
||||||
systemInfoMock = new Mock<ISystemInfo>();
|
|
||||||
textMock = new Mock<IText>();
|
textMock = new Mock<IText>();
|
||||||
uiFactoryMock = new Mock<IUserInterfaceFactory>();
|
uiFactoryMock = new Mock<IUserInterfaceFactory>();
|
||||||
|
|
||||||
uiFactoryMock.Setup(f => f.CreateSplashScreen(runtimeInfoMock.Object, textMock.Object)).Returns(new Mock<ISplashScreen>().Object);
|
uiFactoryMock.Setup(f => f.CreateSplashScreen(runtimeInfoMock.Object, textMock.Object)).Returns(new Mock<ISplashScreen>().Object);
|
||||||
|
|
||||||
sut = new StartupController(loggerMock.Object, runtimeInfoMock.Object, systemInfoMock.Object, textMock.Object, uiFactoryMock.Object);
|
sut = new OperationSequence(loggerMock.Object, runtimeInfoMock.Object, textMock.Object, uiFactoryMock.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#region Perform Tests
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void MustCorrectlyAbortProcess()
|
public void MustCorrectlyAbortProcess()
|
||||||
{
|
{
|
||||||
|
@ -52,13 +51,13 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
|
||||||
var operationC = new Mock<IOperation>();
|
var operationC = new Mock<IOperation>();
|
||||||
var operations = new Queue<IOperation>();
|
var operations = new Queue<IOperation>();
|
||||||
|
|
||||||
operationB.SetupGet(o => o.AbortStartup).Returns(true);
|
operationB.SetupGet(o => o.Abort).Returns(true);
|
||||||
|
|
||||||
operations.Enqueue(operationA.Object);
|
operations.Enqueue(operationA.Object);
|
||||||
operations.Enqueue(operationB.Object);
|
operations.Enqueue(operationB.Object);
|
||||||
operations.Enqueue(operationC.Object);
|
operations.Enqueue(operationC.Object);
|
||||||
|
|
||||||
var result = sut.TryInitializeApplication(operations);
|
var success = sut.TryPerform(operations);
|
||||||
|
|
||||||
operationA.Verify(o => o.Perform(), Times.Once);
|
operationA.Verify(o => o.Perform(), Times.Once);
|
||||||
operationA.Verify(o => o.Revert(), Times.Once);
|
operationA.Verify(o => o.Revert(), Times.Once);
|
||||||
|
@ -67,7 +66,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
|
||||||
operationC.Verify(o => o.Perform(), Times.Never);
|
operationC.Verify(o => o.Perform(), Times.Never);
|
||||||
operationC.Verify(o => o.Revert(), Times.Never);
|
operationC.Verify(o => o.Revert(), Times.Never);
|
||||||
|
|
||||||
Assert.IsFalse(result);
|
Assert.IsFalse(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -82,7 +81,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
|
||||||
operations.Enqueue(operationB.Object);
|
operations.Enqueue(operationB.Object);
|
||||||
operations.Enqueue(operationC.Object);
|
operations.Enqueue(operationC.Object);
|
||||||
|
|
||||||
var result = sut.TryInitializeApplication(operations);
|
var success = sut.TryPerform(operations);
|
||||||
|
|
||||||
operationA.Verify(o => o.Perform(), Times.Once);
|
operationA.Verify(o => o.Perform(), Times.Once);
|
||||||
operationA.Verify(o => o.Revert(), Times.Never);
|
operationA.Verify(o => o.Revert(), Times.Never);
|
||||||
|
@ -91,7 +90,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
|
||||||
operationC.Verify(o => o.Perform(), Times.Once);
|
operationC.Verify(o => o.Perform(), Times.Once);
|
||||||
operationC.Verify(o => o.Revert(), Times.Never);
|
operationC.Verify(o => o.Revert(), Times.Never);
|
||||||
|
|
||||||
Assert.IsTrue(result);
|
Assert.IsTrue(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -111,8 +110,9 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
|
||||||
operations.Enqueue(operationB.Object);
|
operations.Enqueue(operationB.Object);
|
||||||
operations.Enqueue(operationC.Object);
|
operations.Enqueue(operationC.Object);
|
||||||
|
|
||||||
sut.TryInitializeApplication(operations);
|
var success = sut.TryPerform(operations);
|
||||||
|
|
||||||
|
Assert.IsTrue(success);
|
||||||
Assert.IsTrue(a == 1);
|
Assert.IsTrue(a == 1);
|
||||||
Assert.IsTrue(b == 2);
|
Assert.IsTrue(b == 2);
|
||||||
Assert.IsTrue(c == 3);
|
Assert.IsTrue(c == 3);
|
||||||
|
@ -134,7 +134,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
|
||||||
operations.Enqueue(operationC.Object);
|
operations.Enqueue(operationC.Object);
|
||||||
operations.Enqueue(operationD.Object);
|
operations.Enqueue(operationD.Object);
|
||||||
|
|
||||||
var result = sut.TryInitializeApplication(operations);
|
var success = sut.TryPerform(operations);
|
||||||
|
|
||||||
operationA.Verify(o => o.Perform(), Times.Once);
|
operationA.Verify(o => o.Perform(), Times.Once);
|
||||||
operationA.Verify(o => o.Revert(), Times.Once);
|
operationA.Verify(o => o.Revert(), Times.Once);
|
||||||
|
@ -145,11 +145,11 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
|
||||||
operationD.Verify(o => o.Perform(), Times.Never);
|
operationD.Verify(o => o.Perform(), Times.Never);
|
||||||
operationD.Verify(o => o.Revert(), Times.Never);
|
operationD.Verify(o => o.Revert(), Times.Never);
|
||||||
|
|
||||||
Assert.IsFalse(result);
|
Assert.IsFalse(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void MustRevertOperationsInSequence()
|
public void MustRevertOperationsInSequenceAfterPerformError()
|
||||||
{
|
{
|
||||||
int current = 0, a = 0, b = 0, c = 0, d = 0;
|
int current = 0, a = 0, b = 0, c = 0, d = 0;
|
||||||
var operationA = new Mock<IOperation>();
|
var operationA = new Mock<IOperation>();
|
||||||
|
@ -169,8 +169,9 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
|
||||||
operations.Enqueue(operationC.Object);
|
operations.Enqueue(operationC.Object);
|
||||||
operations.Enqueue(operationD.Object);
|
operations.Enqueue(operationD.Object);
|
||||||
|
|
||||||
sut.TryInitializeApplication(operations);
|
var success = sut.TryPerform(operations);
|
||||||
|
|
||||||
|
Assert.IsFalse(success);
|
||||||
Assert.IsTrue(d == 0);
|
Assert.IsTrue(d == 0);
|
||||||
Assert.IsTrue(c == 1);
|
Assert.IsTrue(c == 1);
|
||||||
Assert.IsTrue(b == 2);
|
Assert.IsTrue(b == 2);
|
||||||
|
@ -178,7 +179,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void MustContinueToRevertOperationsInCaseOfError()
|
public void MustContinueToRevertOperationsAfterPerformError()
|
||||||
{
|
{
|
||||||
var operationA = new Mock<IOperation>();
|
var operationA = new Mock<IOperation>();
|
||||||
var operationB = new Mock<IOperation>();
|
var operationB = new Mock<IOperation>();
|
||||||
|
@ -194,7 +195,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
|
||||||
operations.Enqueue(operationB.Object);
|
operations.Enqueue(operationB.Object);
|
||||||
operations.Enqueue(operationC.Object);
|
operations.Enqueue(operationC.Object);
|
||||||
|
|
||||||
var result = sut.TryInitializeApplication(operations);
|
var result = sut.TryPerform(operations);
|
||||||
|
|
||||||
operationA.Verify(o => o.Perform(), Times.Once);
|
operationA.Verify(o => o.Perform(), Times.Once);
|
||||||
operationA.Verify(o => o.Revert(), Times.Once);
|
operationA.Verify(o => o.Revert(), Times.Once);
|
||||||
|
@ -207,7 +208,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
public void MustSucceedWithEmptyQueue()
|
public void MustSucceedWithEmptyQueue()
|
||||||
{
|
{
|
||||||
var result = sut.TryInitializeApplication(new Queue<IOperation>());
|
var result = sut.TryPerform(new Queue<IOperation>());
|
||||||
|
|
||||||
Assert.IsTrue(result);
|
Assert.IsTrue(result);
|
||||||
}
|
}
|
||||||
|
@ -217,7 +218,151 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
|
||||||
public void MustNotFailInCaseOfUnexpectedError()
|
public void MustNotFailInCaseOfUnexpectedError()
|
||||||
{
|
{
|
||||||
uiFactoryMock.Setup(l => l.CreateSplashScreen(It.IsAny<IRuntimeInfo>(), It.IsAny<IText>())).Throws(new Exception());
|
uiFactoryMock.Setup(l => l.CreateSplashScreen(It.IsAny<IRuntimeInfo>(), It.IsAny<IText>())).Throws(new Exception());
|
||||||
sut.TryInitializeApplication(new Queue<IOperation>());
|
|
||||||
|
var success = sut.TryPerform(new Queue<IOperation>());
|
||||||
|
|
||||||
|
Assert.IsFalse(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Repeat Tests
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void Fail()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
Assert.Fail();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Revert Tests
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MustRevertOperations()
|
||||||
|
{
|
||||||
|
var operationA = new Mock<IOperation>();
|
||||||
|
var operationB = new Mock<IOperation>();
|
||||||
|
var operationC = new Mock<IOperation>();
|
||||||
|
var operations = new Queue<IOperation>();
|
||||||
|
|
||||||
|
operations.Enqueue(operationA.Object);
|
||||||
|
operations.Enqueue(operationB.Object);
|
||||||
|
operations.Enqueue(operationC.Object);
|
||||||
|
|
||||||
|
sut.TryPerform(operations);
|
||||||
|
|
||||||
|
var success = sut.TryRevert();
|
||||||
|
|
||||||
|
operationA.Verify(o => o.Revert(), Times.Once);
|
||||||
|
operationB.Verify(o => o.Revert(), Times.Once);
|
||||||
|
operationC.Verify(o => o.Revert(), Times.Once);
|
||||||
|
|
||||||
|
Assert.IsTrue(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MustRevertOperationsInSequence()
|
||||||
|
{
|
||||||
|
int current = 0, a = 0, b = 0, c = 0;
|
||||||
|
var operationA = new Mock<IOperation>();
|
||||||
|
var operationB = new Mock<IOperation>();
|
||||||
|
var operationC = new Mock<IOperation>();
|
||||||
|
var operations = new Queue<IOperation>();
|
||||||
|
|
||||||
|
operationA.Setup(o => o.Revert()).Callback(() => a = ++current);
|
||||||
|
operationB.Setup(o => o.Revert()).Callback(() => b = ++current);
|
||||||
|
operationC.Setup(o => o.Revert()).Callback(() => c = ++current);
|
||||||
|
|
||||||
|
operations.Enqueue(operationA.Object);
|
||||||
|
operations.Enqueue(operationB.Object);
|
||||||
|
operations.Enqueue(operationC.Object);
|
||||||
|
|
||||||
|
sut.TryPerform(operations);
|
||||||
|
|
||||||
|
var success = sut.TryRevert();
|
||||||
|
|
||||||
|
Assert.IsTrue(success);
|
||||||
|
Assert.IsTrue(c == 1);
|
||||||
|
Assert.IsTrue(b == 2);
|
||||||
|
Assert.IsTrue(a == 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MustContinueToRevertOperationsInCaseOfError()
|
||||||
|
{
|
||||||
|
var operationA = new Mock<IOperation>();
|
||||||
|
var operationB = new Mock<IOperation>();
|
||||||
|
var operationC = new Mock<IOperation>();
|
||||||
|
var operations = new Queue<IOperation>();
|
||||||
|
|
||||||
|
operationA.Setup(o => o.Revert()).Throws<Exception>();
|
||||||
|
operationB.Setup(o => o.Revert()).Throws<Exception>();
|
||||||
|
operationC.Setup(o => o.Revert()).Throws<Exception>();
|
||||||
|
|
||||||
|
operations.Enqueue(operationA.Object);
|
||||||
|
operations.Enqueue(operationB.Object);
|
||||||
|
operations.Enqueue(operationC.Object);
|
||||||
|
|
||||||
|
sut.TryPerform(operations);
|
||||||
|
|
||||||
|
var success = sut.TryRevert();
|
||||||
|
|
||||||
|
operationA.Verify(o => o.Revert(), Times.Once);
|
||||||
|
operationB.Verify(o => o.Revert(), Times.Once);
|
||||||
|
operationC.Verify(o => o.Revert(), Times.Once);
|
||||||
|
|
||||||
|
Assert.IsFalse(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MustOnlyRevertPerformedOperations()
|
||||||
|
{
|
||||||
|
var operationA = new Mock<IOperation>();
|
||||||
|
var operationB = new Mock<IOperation>();
|
||||||
|
var operationC = new Mock<IOperation>();
|
||||||
|
var operations = new Queue<IOperation>();
|
||||||
|
|
||||||
|
operationB.SetupGet(o => o.Abort).Returns(true);
|
||||||
|
|
||||||
|
operations.Enqueue(operationA.Object);
|
||||||
|
operations.Enqueue(operationB.Object);
|
||||||
|
operations.Enqueue(operationC.Object);
|
||||||
|
|
||||||
|
sut.TryPerform(operations);
|
||||||
|
|
||||||
|
var success = sut.TryRevert();
|
||||||
|
|
||||||
|
operationA.Verify(o => o.Revert(), Times.Once);
|
||||||
|
operationB.Verify(o => o.Revert(), Times.Once);
|
||||||
|
operationC.Verify(o => o.Revert(), Times.Never);
|
||||||
|
|
||||||
|
Assert.IsTrue(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MustNotFailWithEmptyQueueWhenReverting()
|
||||||
|
{
|
||||||
|
sut.TryPerform(new Queue<IOperation>());
|
||||||
|
sut.TryRevert();
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MustNotFailWithoutPerformWhenReverting()
|
||||||
|
{
|
||||||
|
var success = sut.TryRevert();
|
||||||
|
|
||||||
|
Assert.IsTrue(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MustNotFailInCaseOfUnexpectedErrorWhenReverting()
|
||||||
|
{
|
||||||
|
uiFactoryMock.Setup(l => l.CreateSplashScreen(It.IsAny<IRuntimeInfo>(), It.IsAny<IText>())).Throws(new Exception());
|
||||||
|
sut.TryRevert();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,148 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
using Moq;
|
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
|
||||||
using SafeExamBrowser.Contracts.Configuration;
|
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
|
||||||
using SafeExamBrowser.Core.Behaviour;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.Core.UnitTests.Behaviour
|
|
||||||
{
|
|
||||||
[TestClass]
|
|
||||||
public class ShutdownControllerTests
|
|
||||||
{
|
|
||||||
private Mock<ILogger> loggerMock;
|
|
||||||
private Mock<IRuntimeInfo> runtimeInfoMock;
|
|
||||||
private Mock<IText> textMock;
|
|
||||||
private Mock<IUserInterfaceFactory> uiFactoryMock;
|
|
||||||
|
|
||||||
private IShutdownController sut;
|
|
||||||
|
|
||||||
[TestInitialize]
|
|
||||||
public void Initialize()
|
|
||||||
{
|
|
||||||
loggerMock = new Mock<ILogger>();
|
|
||||||
runtimeInfoMock = new Mock<IRuntimeInfo>();
|
|
||||||
textMock = new Mock<IText>();
|
|
||||||
uiFactoryMock = new Mock<IUserInterfaceFactory>();
|
|
||||||
|
|
||||||
uiFactoryMock.Setup(f => f.CreateSplashScreen(runtimeInfoMock.Object, textMock.Object)).Returns(new Mock<ISplashScreen>().Object);
|
|
||||||
|
|
||||||
sut = new ShutdownController(loggerMock.Object, runtimeInfoMock.Object, textMock.Object, uiFactoryMock.Object);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void MustRevertOperations()
|
|
||||||
{
|
|
||||||
var operationA = new Mock<IOperation>();
|
|
||||||
var operationB = new Mock<IOperation>();
|
|
||||||
var operationC = new Mock<IOperation>();
|
|
||||||
var operations = new Queue<IOperation>();
|
|
||||||
|
|
||||||
operations.Enqueue(operationA.Object);
|
|
||||||
operations.Enqueue(operationB.Object);
|
|
||||||
operations.Enqueue(operationC.Object);
|
|
||||||
|
|
||||||
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]
|
|
||||||
public void MustRevertOperationsInSequence()
|
|
||||||
{
|
|
||||||
int current = 0, a = 0, b = 0, c = 0;
|
|
||||||
var operationA = new Mock<IOperation>();
|
|
||||||
var operationB = new Mock<IOperation>();
|
|
||||||
var operationC = new Mock<IOperation>();
|
|
||||||
var operations = new Queue<IOperation>();
|
|
||||||
|
|
||||||
operationA.Setup(o => o.Revert()).Callback(() => a = ++current);
|
|
||||||
operationB.Setup(o => o.Revert()).Callback(() => b = ++current);
|
|
||||||
operationC.Setup(o => o.Revert()).Callback(() => c = ++current);
|
|
||||||
|
|
||||||
operations.Enqueue(operationA.Object);
|
|
||||||
operations.Enqueue(operationB.Object);
|
|
||||||
operations.Enqueue(operationC.Object);
|
|
||||||
|
|
||||||
sut.FinalizeApplication(operations);
|
|
||||||
|
|
||||||
Assert.IsTrue(a == 1);
|
|
||||||
Assert.IsTrue(b == 2);
|
|
||||||
Assert.IsTrue(c == 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void MustContinueToRevertOperationsInCaseOfError()
|
|
||||||
{
|
|
||||||
var operationA = new Mock<IOperation>();
|
|
||||||
var operationB = new Mock<IOperation>();
|
|
||||||
var operationC = new Mock<IOperation>();
|
|
||||||
var operations = new Queue<IOperation>();
|
|
||||||
|
|
||||||
operationA.Setup(o => o.Revert()).Throws<Exception>();
|
|
||||||
operationB.Setup(o => o.Revert()).Throws<Exception>();
|
|
||||||
operationC.Setup(o => o.Revert()).Throws<Exception>();
|
|
||||||
|
|
||||||
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 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]
|
|
||||||
public void MustNotFailWithEmptyQueue()
|
|
||||||
{
|
|
||||||
sut.FinalizeApplication(new Queue<IOperation>());
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestMethod]
|
|
||||||
public void MustNotFailInCaseOfUnexpectedError()
|
|
||||||
{
|
|
||||||
uiFactoryMock.Setup(l => l.CreateSplashScreen(It.IsAny<IRuntimeInfo>(), It.IsAny<IText>())).Throws(new Exception());
|
|
||||||
sut.FinalizeApplication(new Queue<IOperation>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -79,8 +79,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Behaviour\Operations\I18nOperationTests.cs" />
|
<Compile Include="Behaviour\Operations\I18nOperationTests.cs" />
|
||||||
<Compile Include="Behaviour\StartupControllerTests.cs" />
|
<Compile Include="Behaviour\Operations\OperationSequenceTests.cs" />
|
||||||
<Compile Include="Behaviour\ShutdownControllerTests.cs" />
|
|
||||||
<Compile Include="I18n\TextTests.cs" />
|
<Compile Include="I18n\TextTests.cs" />
|
||||||
<Compile Include="I18n\XmlTextResourceTests.cs" />
|
<Compile Include="I18n\XmlTextResourceTests.cs" />
|
||||||
<Compile Include="Logging\DefaultLogFormatterTests.cs" />
|
<Compile Include="Logging\DefaultLogFormatterTests.cs" />
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
using SafeExamBrowser.Contracts.UserInterface;
|
||||||
|
@ -22,7 +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 bool Abort { 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)
|
||||||
|
@ -42,6 +42,11 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
||||||
text.Initialize(textResource);
|
text.Initialize(textResource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Repeat()
|
||||||
|
{
|
||||||
|
// Nothing to do here...
|
||||||
|
}
|
||||||
|
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
// Nothing to do here...
|
// Nothing to do here...
|
||||||
|
|
|
@ -9,35 +9,33 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.Configuration;
|
using SafeExamBrowser.Contracts.Configuration;
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
using SafeExamBrowser.Contracts.UserInterface;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Core.Behaviour
|
namespace SafeExamBrowser.Core.Behaviour.Operations
|
||||||
{
|
{
|
||||||
public class StartupController : IStartupController
|
public class OperationSequence : IOperationSequence
|
||||||
{
|
{
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private IRuntimeInfo runtimeInfo;
|
private IRuntimeInfo runtimeInfo;
|
||||||
private ISplashScreen splashScreen;
|
private ISplashScreen splashScreen;
|
||||||
private ISystemInfo systemInfo;
|
|
||||||
private IText text;
|
private IText text;
|
||||||
private IUserInterfaceFactory uiFactory;
|
private IUserInterfaceFactory uiFactory;
|
||||||
|
|
||||||
private Stack<IOperation> stack = new Stack<IOperation>();
|
private Stack<IOperation> stack = new Stack<IOperation>();
|
||||||
|
|
||||||
public StartupController(ILogger logger, IRuntimeInfo runtimeInfo, ISystemInfo systemInfo, IText text, IUserInterfaceFactory uiFactory)
|
public OperationSequence(ILogger logger, IRuntimeInfo runtimeInfo, IText text, IUserInterfaceFactory uiFactory)
|
||||||
{
|
{
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.runtimeInfo = runtimeInfo;
|
this.runtimeInfo = runtimeInfo;
|
||||||
this.systemInfo = systemInfo;
|
|
||||||
this.text = text;
|
this.text = text;
|
||||||
this.uiFactory = uiFactory;
|
this.uiFactory = uiFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryInitializeApplication(Queue<IOperation> operations)
|
public bool TryPerform(Queue<IOperation> operations)
|
||||||
{
|
{
|
||||||
var success = false;
|
var success = false;
|
||||||
|
|
||||||
|
@ -50,18 +48,62 @@ namespace SafeExamBrowser.Core.Behaviour
|
||||||
{
|
{
|
||||||
RevertOperations();
|
RevertOperations();
|
||||||
}
|
}
|
||||||
|
|
||||||
Finish(success);
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LogAndShowException(e);
|
logger.Error($"Failed to perform operations!", e);
|
||||||
Finish(false);
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool TryRepeat()
|
||||||
|
{
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryRevert()
|
||||||
|
{
|
||||||
|
var success = false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Initialize();
|
||||||
|
success = RevertOperations(false);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
logger.Error($"Failed to revert operations!", e);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Initialize(int? operationCount = null)
|
||||||
|
{
|
||||||
|
splashScreen = uiFactory.CreateSplashScreen(runtimeInfo, text);
|
||||||
|
|
||||||
|
if (operationCount.HasValue)
|
||||||
|
{
|
||||||
|
splashScreen.SetMaxProgress(operationCount.Value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
splashScreen.SetIndeterminate();
|
||||||
|
}
|
||||||
|
|
||||||
|
splashScreen.UpdateText(TextKey.SplashScreen_StartupProcedure);
|
||||||
|
splashScreen.Show();
|
||||||
|
}
|
||||||
|
|
||||||
private bool Perform(Queue<IOperation> operations)
|
private bool Perform(Queue<IOperation> operations)
|
||||||
{
|
{
|
||||||
foreach (var operation in operations)
|
foreach (var operation in operations)
|
||||||
|
@ -75,12 +117,12 @@ namespace SafeExamBrowser.Core.Behaviour
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LogAndShowException(e);
|
logger.Error($"Failed to perform operation '{operation.GetType().Name}'!", e);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (operation.AbortStartup)
|
if (operation.Abort)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -91,8 +133,10 @@ namespace SafeExamBrowser.Core.Behaviour
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RevertOperations()
|
private bool RevertOperations(bool regress = true)
|
||||||
{
|
{
|
||||||
|
var success = true;
|
||||||
|
|
||||||
while (stack.Any())
|
while (stack.Any())
|
||||||
{
|
{
|
||||||
var operation = stack.Pop();
|
var operation = stack.Pop();
|
||||||
|
@ -104,41 +148,20 @@ namespace SafeExamBrowser.Core.Behaviour
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
logger.Error($"Failed to revert operation '{operation.GetType().Name}'!", e);
|
logger.Error($"Failed to revert operation '{operation.GetType().Name}'!", e);
|
||||||
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (regress)
|
||||||
|
{
|
||||||
splashScreen.Regress();
|
splashScreen.Regress();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Initialize(int operationCount)
|
return success;
|
||||||
{
|
|
||||||
logger.Info("--- Initiating startup procedure ---");
|
|
||||||
|
|
||||||
splashScreen = uiFactory.CreateSplashScreen(runtimeInfo, text);
|
|
||||||
splashScreen.SetMaxProgress(operationCount);
|
|
||||||
splashScreen.UpdateText(TextKey.SplashScreen_StartupProcedure);
|
|
||||||
splashScreen.Show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void LogAndShowException(Exception e)
|
private void Finish()
|
||||||
{
|
{
|
||||||
logger.Error($"Failed to initialize application!", e);
|
|
||||||
uiFactory.Show(text.Get(TextKey.MessageBox_StartupError), text.Get(TextKey.MessageBox_StartupErrorTitle), icon: MessageBoxIcon.Error);
|
|
||||||
logger.Info("Reverting operations...");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Finish(bool success = true)
|
|
||||||
{
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
logger.Info("--- Application successfully initialized! ---");
|
|
||||||
logger.Log(string.Empty);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.Info("--- Startup procedure aborted! ---");
|
|
||||||
}
|
|
||||||
|
|
||||||
splashScreen?.Close();
|
splashScreen?.Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,98 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2018 ETH Zürich, Educational Development and Technology (LET)
|
|
||||||
*
|
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
|
||||||
using SafeExamBrowser.Contracts.Configuration;
|
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.Core.Behaviour
|
|
||||||
{
|
|
||||||
public class ShutdownController : IShutdownController
|
|
||||||
{
|
|
||||||
private ILogger logger;
|
|
||||||
private IRuntimeInfo runtimeInfo;
|
|
||||||
private ISplashScreen splashScreen;
|
|
||||||
private IText text;
|
|
||||||
private IUserInterfaceFactory uiFactory;
|
|
||||||
|
|
||||||
public ShutdownController(ILogger logger, IRuntimeInfo runtimeInfo, IText text, IUserInterfaceFactory uiFactory)
|
|
||||||
{
|
|
||||||
this.logger = logger;
|
|
||||||
this.runtimeInfo = runtimeInfo;
|
|
||||||
this.text = text;
|
|
||||||
this.uiFactory = uiFactory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void FinalizeApplication(Queue<IOperation> operations)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Initialize();
|
|
||||||
Revert(operations);
|
|
||||||
Finish();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
LogAndShowException(e);
|
|
||||||
Finish(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Revert(Queue<IOperation> operations)
|
|
||||||
{
|
|
||||||
foreach (var operation in operations)
|
|
||||||
{
|
|
||||||
operation.SplashScreen = splashScreen;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
operation.Revert();
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
logger.Error($"Failed to revert operation '{operation.GetType().Name}'!", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Initialize()
|
|
||||||
{
|
|
||||||
logger.Log(string.Empty);
|
|
||||||
logger.Info("--- Initiating shutdown procedure ---");
|
|
||||||
|
|
||||||
splashScreen = uiFactory.CreateSplashScreen(runtimeInfo, text);
|
|
||||||
splashScreen.SetIndeterminate();
|
|
||||||
splashScreen.UpdateText(TextKey.SplashScreen_ShutdownProcedure);
|
|
||||||
splashScreen.Show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void LogAndShowException(Exception e)
|
|
||||||
{
|
|
||||||
logger.Error($"Failed to finalize application!", e);
|
|
||||||
uiFactory.Show(text.Get(TextKey.MessageBox_ShutdownError), text.Get(TextKey.MessageBox_ShutdownErrorTitle), icon: MessageBoxIcon.Error);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void Finish(bool success = true)
|
|
||||||
{
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
logger.Info("--- Application successfully finalized! ---");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.Info("--- Shutdown procedure failed! ---");
|
|
||||||
}
|
|
||||||
|
|
||||||
splashScreen?.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -56,8 +56,7 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Behaviour\Operations\I18nOperation.cs" />
|
<Compile Include="Behaviour\Operations\I18nOperation.cs" />
|
||||||
<Compile Include="Behaviour\ShutdownController.cs" />
|
<Compile Include="Behaviour\Operations\OperationSequence.cs" />
|
||||||
<Compile Include="Behaviour\StartupController.cs" />
|
|
||||||
<Compile Include="Communication\BaseProxy.cs" />
|
<Compile Include="Communication\BaseProxy.cs" />
|
||||||
<Compile Include="Communication\Messages\Message.cs" />
|
<Compile Include="Communication\Messages\Message.cs" />
|
||||||
<Compile Include="Communication\ServiceProxy.cs" />
|
<Compile Include="Communication\ServiceProxy.cs" />
|
||||||
|
|
|
@ -166,7 +166,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
||||||
|
|
||||||
sut.Perform();
|
sut.Perform();
|
||||||
|
|
||||||
Assert.IsTrue(sut.AbortStartup);
|
Assert.IsTrue(sut.Abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -181,7 +181,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
||||||
|
|
||||||
sut.Perform();
|
sut.Perform();
|
||||||
|
|
||||||
Assert.IsFalse(sut.AbortStartup);
|
Assert.IsFalse(sut.Abort);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
||||||
|
|
||||||
sut.Perform();
|
sut.Perform();
|
||||||
|
|
||||||
Assert.IsTrue(sut.AbortStartup);
|
Assert.IsTrue(sut.Abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
@ -103,7 +103,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
||||||
sut.Perform();
|
sut.Perform();
|
||||||
|
|
||||||
service.VerifySet(s => s.Ignore = true);
|
service.VerifySet(s => s.Ignore = true);
|
||||||
Assert.IsFalse(sut.AbortStartup);
|
Assert.IsFalse(sut.Abort);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|
|
@ -60,13 +60,9 @@ namespace SafeExamBrowser.Runtime
|
||||||
instances.BuildObjectGraph();
|
instances.BuildObjectGraph();
|
||||||
instances.LogStartupInformation();
|
instances.LogStartupInformation();
|
||||||
|
|
||||||
var success = instances.RuntimeController.TryInitializeApplication(instances.StartupOperations);
|
var success = instances.RuntimeController.TryStart(instances.StartupOperations);
|
||||||
|
|
||||||
if (success)
|
if (!success)
|
||||||
{
|
|
||||||
instances.RuntimeController.StartSession();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
Shutdown();
|
Shutdown();
|
||||||
}
|
}
|
||||||
|
@ -74,7 +70,7 @@ namespace SafeExamBrowser.Runtime
|
||||||
|
|
||||||
protected override void OnExit(ExitEventArgs e)
|
protected override void OnExit(ExitEventArgs e)
|
||||||
{
|
{
|
||||||
instances.RuntimeController.FinalizeApplication();
|
instances.RuntimeController.Terminate();
|
||||||
instances.LogShutdownInformation();
|
instances.LogShutdownInformation();
|
||||||
|
|
||||||
base.OnExit(e);
|
base.OnExit(e);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.Configuration;
|
using SafeExamBrowser.Contracts.Configuration;
|
||||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
|
@ -26,7 +26,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 bool Abort { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public ISplashScreen SplashScreen { private get; set; }
|
||||||
|
|
||||||
public ConfigurationOperation(
|
public ConfigurationOperation(
|
||||||
|
@ -60,8 +60,8 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
|
|
||||||
if (settings.ConfigurationMode == ConfigurationMode.ConfigureClient && UserWantsToAbortStartup())
|
if (settings.ConfigurationMode == ConfigurationMode.ConfigureClient && UserWantsToAbortStartup())
|
||||||
{
|
{
|
||||||
AbortStartup = true;
|
Abort = true;
|
||||||
logger.Info($"The user chose to {(AbortStartup ? "abort" : "continue")} the application startup after successful client configuration.");
|
logger.Info($"The user chose to {(Abort ? "abort" : "continue")} the application startup after successful client configuration.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -71,6 +71,11 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Repeat()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
// Nothing to do here...
|
// Nothing to do here...
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
|
@ -20,7 +20,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
private ISettingsRepository settingsRepository;
|
private ISettingsRepository settingsRepository;
|
||||||
private KioskMode kioskMode;
|
private KioskMode kioskMode;
|
||||||
|
|
||||||
public bool AbortStartup { get; private set; }
|
public bool Abort { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public ISplashScreen SplashScreen { private get; set; }
|
||||||
|
|
||||||
public KioskModeOperation(ILogger logger, ISettingsRepository settingsRepository)
|
public KioskModeOperation(ILogger logger, ISettingsRepository settingsRepository)
|
||||||
|
@ -46,6 +46,11 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Repeat()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
logger.Info($"Reverting kiosk mode '{kioskMode}'...");
|
logger.Info($"Reverting kiosk mode '{kioskMode}'...");
|
||||||
|
@ -63,22 +68,22 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
|
|
||||||
private void CreateNewDesktop()
|
private void CreateNewDesktop()
|
||||||
{
|
{
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CloseNewDesktop()
|
private void CloseNewDesktop()
|
||||||
{
|
{
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DisableExplorerShell()
|
private void DisableExplorerShell()
|
||||||
{
|
{
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RestartExplorerShell()
|
private void RestartExplorerShell()
|
||||||
{
|
{
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.Communication;
|
using SafeExamBrowser.Contracts.Communication;
|
||||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||||
using SafeExamBrowser.Contracts.I18n;
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
|
@ -25,7 +25,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
private ISettingsRepository settingsRepository;
|
private ISettingsRepository settingsRepository;
|
||||||
private IText text;
|
private IText text;
|
||||||
|
|
||||||
public bool AbortStartup { get; private set; }
|
public bool Abort { get; private set; }
|
||||||
public ISplashScreen SplashScreen { private get; set; }
|
public ISplashScreen SplashScreen { private get; set; }
|
||||||
|
|
||||||
public ServiceOperation(ILogger logger, IServiceProxy service, ISettingsRepository settingsRepository, IText text)
|
public ServiceOperation(ILogger logger, IServiceProxy service, ISettingsRepository settingsRepository, IText text)
|
||||||
|
@ -48,34 +48,26 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
var message = "Failed to connect to the service component!";
|
LogException(e);
|
||||||
|
|
||||||
if (serviceMandatory)
|
|
||||||
{
|
|
||||||
logger.Error(message, e);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logger.Info($"{message} Reason: {e.Message}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (serviceMandatory && !serviceAvailable)
|
if (serviceMandatory && !serviceAvailable)
|
||||||
{
|
{
|
||||||
AbortStartup = true;
|
Abort = true;
|
||||||
logger.Info("Aborting startup because the service is mandatory but not available!");
|
logger.Info("Aborting startup because the service is mandatory but not available!");
|
||||||
}
|
}
|
||||||
else if (!serviceAvailable)
|
|
||||||
{
|
|
||||||
service.Ignore = true;
|
|
||||||
logger.Info("All service-related operations will be ignored, since the service is optional and not available.");
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logger.Info($"The service is {(serviceMandatory ? "mandatory" : "optional")} and available.");
|
service.Ignore = !serviceAvailable;
|
||||||
|
logger.Info($"The service is {(serviceMandatory ? "mandatory" : "optional")} and {(serviceAvailable ? "available." : "not available. All service-related operations will be ignored!")}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Repeat()
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
logger.Info("Closing service connection...");
|
logger.Info("Closing service connection...");
|
||||||
|
@ -93,5 +85,19 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void LogException(Exception e)
|
||||||
|
{
|
||||||
|
var message = "Failed to connect to the service component!";
|
||||||
|
|
||||||
|
if (serviceMandatory)
|
||||||
|
{
|
||||||
|
logger.Error(message, e);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Info($"{message} Reason: {e.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour;
|
||||||
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.Communication;
|
using SafeExamBrowser.Contracts.Communication;
|
||||||
using SafeExamBrowser.Contracts.Configuration;
|
using SafeExamBrowser.Contracts.Configuration;
|
||||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||||
|
@ -21,52 +21,56 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
||||||
{
|
{
|
||||||
internal class RuntimeController : IRuntimeController
|
internal class RuntimeController : IRuntimeController
|
||||||
{
|
{
|
||||||
private Queue<IOperation> operations;
|
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private IRuntimeInfo runtimeInfo;
|
private IRuntimeInfo runtimeInfo;
|
||||||
private IRuntimeWindow runtimeWindow;
|
private IRuntimeWindow runtimeWindow;
|
||||||
private IServiceProxy serviceProxy;
|
private IServiceProxy serviceProxy;
|
||||||
private ISettingsRepository settingsRepository;
|
private ISettingsRepository settingsRepository;
|
||||||
private IShutdownController shutdownController;
|
private IOperationSequence operationSequence;
|
||||||
private IStartupController startupController;
|
|
||||||
private Action terminationCallback;
|
private Action terminationCallback;
|
||||||
private IText text;
|
private IText text;
|
||||||
private IUserInterfaceFactory uiFactory;
|
private IUserInterfaceFactory uiFactory;
|
||||||
|
|
||||||
public RuntimeController(
|
public RuntimeController(
|
||||||
ILogger logger,
|
ILogger logger,
|
||||||
|
IOperationSequence operationSequence,
|
||||||
IRuntimeInfo runtimeInfo,
|
IRuntimeInfo runtimeInfo,
|
||||||
IServiceProxy serviceProxy,
|
IServiceProxy serviceProxy,
|
||||||
ISettingsRepository settingsRepository,
|
ISettingsRepository settingsRepository,
|
||||||
IShutdownController shutdownController,
|
|
||||||
IStartupController startupController,
|
|
||||||
Action terminationCallback,
|
Action terminationCallback,
|
||||||
IText text,
|
IText text,
|
||||||
IUserInterfaceFactory uiFactory)
|
IUserInterfaceFactory uiFactory)
|
||||||
{
|
{
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
|
this.operationSequence = operationSequence;
|
||||||
this.runtimeInfo = runtimeInfo;
|
this.runtimeInfo = runtimeInfo;
|
||||||
this.serviceProxy = serviceProxy;
|
this.serviceProxy = serviceProxy;
|
||||||
this.settingsRepository = settingsRepository;
|
this.settingsRepository = settingsRepository;
|
||||||
this.shutdownController = shutdownController;
|
|
||||||
this.startupController = startupController;
|
|
||||||
this.terminationCallback = terminationCallback;
|
this.terminationCallback = terminationCallback;
|
||||||
this.text = text;
|
this.text = text;
|
||||||
this.uiFactory = uiFactory;
|
this.uiFactory = uiFactory;
|
||||||
|
|
||||||
operations = new Queue<IOperation>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryInitializeApplication(Queue<IOperation> operations)
|
public bool TryStart(Queue<IOperation> operations)
|
||||||
{
|
{
|
||||||
var success = startupController.TryInitializeApplication(operations);
|
logger.Info("--- Initiating startup procedure ---");
|
||||||
|
|
||||||
|
var success = operationSequence.TryPerform(operations);
|
||||||
|
|
||||||
runtimeWindow = uiFactory.CreateRuntimeWindow(runtimeInfo, text);
|
runtimeWindow = uiFactory.CreateRuntimeWindow(runtimeInfo, text);
|
||||||
|
|
||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
this.operations = new Queue<IOperation>(operations);
|
logger.Info("--- Application successfully initialized! ---");
|
||||||
|
logger.Log(string.Empty);
|
||||||
logger.Subscribe(runtimeWindow);
|
logger.Subscribe(runtimeWindow);
|
||||||
|
|
||||||
|
StartSession();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Info("--- Application startup aborted! ---");
|
||||||
|
logger.Log(string.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
|
@ -95,9 +99,11 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
||||||
{
|
{
|
||||||
runtimeWindow.Hide();
|
runtimeWindow.Hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
terminationCallback.Invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FinalizeApplication()
|
public void Terminate()
|
||||||
{
|
{
|
||||||
StopSession();
|
StopSession();
|
||||||
|
|
||||||
|
@ -108,7 +114,20 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
||||||
|
|
||||||
logger.Unsubscribe(runtimeWindow);
|
logger.Unsubscribe(runtimeWindow);
|
||||||
runtimeWindow.Close();
|
runtimeWindow.Close();
|
||||||
shutdownController.FinalizeApplication(new Queue<IOperation>(operations.Reverse()));
|
|
||||||
|
logger.Log(string.Empty);
|
||||||
|
logger.Info("--- Initiating shutdown procedure ---");
|
||||||
|
|
||||||
|
var success = operationSequence.TryRevert();
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
logger.Info("--- Application successfully finalized! ---");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logger.Info("--- Shutdown procedure failed! ---");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StopSession()
|
private void StopSession()
|
||||||
|
|
|
@ -14,9 +14,9 @@ using System.Windows;
|
||||||
using SafeExamBrowser.Configuration;
|
using SafeExamBrowser.Configuration;
|
||||||
using SafeExamBrowser.Configuration.Settings;
|
using SafeExamBrowser.Configuration.Settings;
|
||||||
using SafeExamBrowser.Contracts.Behaviour;
|
using SafeExamBrowser.Contracts.Behaviour;
|
||||||
|
using SafeExamBrowser.Contracts.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Contracts.Configuration;
|
using SafeExamBrowser.Contracts.Configuration;
|
||||||
using SafeExamBrowser.Contracts.Logging;
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Core.Behaviour;
|
|
||||||
using SafeExamBrowser.Core.Behaviour.Operations;
|
using SafeExamBrowser.Core.Behaviour.Operations;
|
||||||
using SafeExamBrowser.Core.Communication;
|
using SafeExamBrowser.Core.Communication;
|
||||||
using SafeExamBrowser.Core.I18n;
|
using SafeExamBrowser.Core.I18n;
|
||||||
|
@ -52,11 +52,10 @@ namespace SafeExamBrowser.Runtime
|
||||||
InitializeLogging();
|
InitializeLogging();
|
||||||
|
|
||||||
var text = new Text(logger);
|
var text = new Text(logger);
|
||||||
|
var operationSequence = new OperationSequence(logger, runtimeInfo, text, uiFactory);
|
||||||
var serviceProxy = new ServiceProxy(new ModuleLogger(logger, typeof(ServiceProxy)), "net.pipe://localhost/safeexambrowser/service");
|
var serviceProxy = new ServiceProxy(new ModuleLogger(logger, typeof(ServiceProxy)), "net.pipe://localhost/safeexambrowser/service");
|
||||||
var shutdownController = new ShutdownController(logger, runtimeInfo, text, uiFactory);
|
|
||||||
var startupController = new StartupController(logger, runtimeInfo, systemInfo, text, uiFactory);
|
|
||||||
|
|
||||||
RuntimeController = new RuntimeController(new ModuleLogger(logger, typeof(RuntimeController)), runtimeInfo, serviceProxy, settingsRepository, shutdownController, startupController, Application.Current.Shutdown, text, uiFactory);
|
RuntimeController = new RuntimeController(logger, operationSequence, runtimeInfo, serviceProxy, settingsRepository, Application.Current.Shutdown, text, uiFactory);
|
||||||
|
|
||||||
StartupOperations = new Queue<IOperation>();
|
StartupOperations = new Queue<IOperation>();
|
||||||
StartupOperations.Enqueue(new I18nOperation(logger, text));
|
StartupOperations.Enqueue(new I18nOperation(logger, text));
|
||||||
|
|
Loading…
Reference in a new issue