SEBWIN-219: Separated immutable, application-wide configuration values from settings.

This commit is contained in:
dbuechel 2018-01-17 14:08:39 +01:00
parent bb00ef926d
commit 0b52095453
26 changed files with 204 additions and 212 deletions

View file

@ -24,11 +24,17 @@ namespace SafeExamBrowser.Browser
private IApplicationButton button;
private IList<IApplicationInstance> instances = new List<IApplicationInstance>();
private IBrowserSettings settings;
private IRuntimeInfo runtimeInfo;
private IUserInterfaceFactory uiFactory;
private IText text;
public BrowserApplicationController(IBrowserSettings settings, IText text, IUserInterfaceFactory uiFactory)
public BrowserApplicationController(
IBrowserSettings settings,
IRuntimeInfo runtimeInfo,
IText text,
IUserInterfaceFactory uiFactory)
{
this.runtimeInfo = runtimeInfo;
this.settings = settings;
this.text = text;
this.uiFactory = uiFactory;
@ -38,8 +44,8 @@ namespace SafeExamBrowser.Browser
{
var cefSettings = new CefSettings
{
CachePath = settings.CachePath,
LogFile = settings.LogFile
CachePath = runtimeInfo.BrowserCachePath,
LogFile = runtimeInfo.BrowserLogFile
};
var success = Cef.Initialize(cefSettings, true, null);

View file

@ -21,16 +21,8 @@ using SafeExamBrowser.Contracts.SystemComponents;
using SafeExamBrowser.Contracts.UserInterface;
using SafeExamBrowser.Contracts.UserInterface.Taskbar;
using SafeExamBrowser.Contracts.WindowsApi;
using SafeExamBrowser.Core.Behaviour;
using SafeExamBrowser.Core.Behaviour.Operations;
using SafeExamBrowser.Core.I18n;
using SafeExamBrowser.Core.Logging;
using SafeExamBrowser.Monitoring.Display;
using SafeExamBrowser.Monitoring.Keyboard;
using SafeExamBrowser.Monitoring.Mouse;
using SafeExamBrowser.Monitoring.Processes;
using SafeExamBrowser.Monitoring.Windows;
using SafeExamBrowser.SystemComponents;
using SafeExamBrowser.UserInterface.Classic;
using SafeExamBrowser.WindowsApi;
@ -64,46 +56,51 @@ namespace SafeExamBrowser.Client
internal void BuildObjectGraph()
{
browserInfo = new BrowserApplicationInfo();
logger = new Logger();
nativeMethods = new NativeMethods();
settings = new SettingsRepository().LoadDefaults();
systemInfo = new SystemInfo();
uiFactory = new UserInterfaceFactory();
InitializeLogger();
InitializeLogging();
text = new Text(logger);
Taskbar = new Taskbar(new ModuleLogger(logger, typeof(Taskbar)));
browserController = new BrowserApplicationController(settings.Browser, text, uiFactory);
displayMonitor = new DisplayMonitor(new ModuleLogger(logger, typeof(DisplayMonitor)), nativeMethods);
keyboardInterceptor = new KeyboardInterceptor(settings.Keyboard, new ModuleLogger(logger, typeof(KeyboardInterceptor)));
keyboardLayout = new KeyboardLayout(new ModuleLogger(logger, typeof(KeyboardLayout)), text);
mouseInterceptor = new MouseInterceptor(new ModuleLogger(logger, typeof(MouseInterceptor)), settings.Mouse);
powerSupply = new PowerSupply(new ModuleLogger(logger, typeof(PowerSupply)), text);
processMonitor = new ProcessMonitor(new ModuleLogger(logger, typeof(ProcessMonitor)), nativeMethods);
windowMonitor = new WindowMonitor(new ModuleLogger(logger, typeof(WindowMonitor)), nativeMethods);
wirelessNetwork = new WirelessNetwork(new ModuleLogger(logger, typeof(WirelessNetwork)), text);
// TODO
//Taskbar = new Taskbar(new ModuleLogger(logger, typeof(Taskbar)));
//browserController = new BrowserApplicationController(settings.Browser, text, uiFactory);
//displayMonitor = new DisplayMonitor(new ModuleLogger(logger, typeof(DisplayMonitor)), nativeMethods);
//keyboardInterceptor = new KeyboardInterceptor(settings.Keyboard, new ModuleLogger(logger, typeof(KeyboardInterceptor)));
//keyboardLayout = new KeyboardLayout(new ModuleLogger(logger, typeof(KeyboardLayout)), text);
//mouseInterceptor = new MouseInterceptor(new ModuleLogger(logger, typeof(MouseInterceptor)), settings.Mouse);
//powerSupply = new PowerSupply(new ModuleLogger(logger, typeof(PowerSupply)), text);
//processMonitor = new ProcessMonitor(new ModuleLogger(logger, typeof(ProcessMonitor)), nativeMethods);
//windowMonitor = new WindowMonitor(new ModuleLogger(logger, typeof(WindowMonitor)), nativeMethods);
//wirelessNetwork = new WirelessNetwork(new ModuleLogger(logger, typeof(WirelessNetwork)), text);
clientController = new ClientController(displayMonitor, new ModuleLogger(logger, typeof(ClientController)), processMonitor, Taskbar, windowMonitor);
ShutdownController = new ShutdownController(logger, settings, text, uiFactory);
StartupController = new StartupController(logger, settings, systemInfo, text, uiFactory);
//clientController = new ClientController(displayMonitor, new ModuleLogger(logger, typeof(ClientController)), processMonitor, Taskbar, windowMonitor);
//ShutdownController = new ShutdownController(logger, settings, text, uiFactory);
//StartupController = new StartupController(logger, settings, systemInfo, text, uiFactory);
StartupOperations = new Queue<IOperation>();
StartupOperations.Enqueue(new I18nOperation(logger, text));
StartupOperations.Enqueue(new KeyboardInterceptorOperation(keyboardInterceptor, logger, nativeMethods));
StartupOperations.Enqueue(new WindowMonitorOperation(logger, windowMonitor));
StartupOperations.Enqueue(new ProcessMonitorOperation(logger, processMonitor));
StartupOperations.Enqueue(new DisplayMonitorOperation(displayMonitor, logger, Taskbar));
StartupOperations.Enqueue(new TaskbarOperation(logger, settings.Taskbar, keyboardLayout, powerSupply, wirelessNetwork, systemInfo, Taskbar, text, uiFactory));
StartupOperations.Enqueue(new BrowserOperation(browserController, browserInfo, logger, Taskbar, uiFactory));
StartupOperations.Enqueue(new ClientControllerOperation(clientController, logger));
StartupOperations.Enqueue(new ClipboardOperation(logger, nativeMethods));
StartupOperations.Enqueue(new MouseInterceptorOperation(logger, mouseInterceptor, nativeMethods));
//StartupOperations = new Queue<IOperation>();
//StartupOperations.Enqueue(new I18nOperation(logger, text));
//StartupOperations.Enqueue(new KeyboardInterceptorOperation(keyboardInterceptor, logger, nativeMethods));
//StartupOperations.Enqueue(new WindowMonitorOperation(logger, windowMonitor));
//StartupOperations.Enqueue(new ProcessMonitorOperation(logger, processMonitor));
//StartupOperations.Enqueue(new DisplayMonitorOperation(displayMonitor, logger, Taskbar));
//StartupOperations.Enqueue(new TaskbarOperation(logger, settings.Taskbar, keyboardLayout, powerSupply, wirelessNetwork, systemInfo, Taskbar, text, uiFactory));
//StartupOperations.Enqueue(new BrowserOperation(browserController, browserInfo, logger, Taskbar, uiFactory));
//StartupOperations.Enqueue(new ClientControllerOperation(clientController, logger));
//StartupOperations.Enqueue(new ClipboardOperation(logger, nativeMethods));
//StartupOperations.Enqueue(new MouseInterceptorOperation(logger, mouseInterceptor, nativeMethods));
}
private void InitializeLogger()
private void InitializeLogging()
{
logger = new Logger();
logger.Subscribe(new LogFileWriter(new DefaultLogFormatter(), settings.Logging.ClientLogFile));
// TODO
//var logFileWriter = new LogFileWriter(new DefaultLogFormatter(), settings.Logging.ClientLogFile);
//logFileWriter.Initialize();
//logger.Subscribe(logFileWriter);
}
}
}

View file

@ -7,16 +7,21 @@
*/
using System;
using SafeExamBrowser.Contracts.Configuration.Settings;
using SafeExamBrowser.Contracts.Configuration;
namespace SafeExamBrowser.Configuration.Settings
namespace SafeExamBrowser.Configuration
{
[Serializable]
internal class LoggingSettings : ILoggingSettings
public class RuntimeInfo : IRuntimeInfo
{
public string AppDataFolder { get; set; }
public DateTime ApplicationStartTime { get; set; }
public string BrowserCachePath { get; set; }
public string BrowserLogFile { get; set; }
public string ClientLogFile { get; set; }
public string ProgramCopyright { get; set; }
public string ProgramTitle { get; set; }
public string ProgramVersion { get; set; }
public string RuntimeLogFile { get; set; }
}
}

View file

@ -53,9 +53,9 @@
<Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<Compile Include="RuntimeInfo.cs" />
<Compile Include="Settings\BrowserSettings.cs" />
<Compile Include="Settings\KeyboardSettings.cs" />
<Compile Include="Settings\LoggingSettings.cs" />
<Compile Include="Settings\MouseSettings.cs" />
<Compile Include="Settings\Settings.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />

View file

@ -14,22 +14,15 @@ namespace SafeExamBrowser.Configuration.Settings
[Serializable]
internal class Settings : ISettings
{
public string AppDataFolder { get; set; }
public string ProgramCopyright { get; set; }
public string ProgramTitle { get; set; }
public string ProgramVersion { get; set; }
public IBrowserSettings Browser { get; private set; }
public IKeyboardSettings Keyboard { get; private set; }
public ILoggingSettings Logging { get; private set; }
public IMouseSettings Mouse { get; private set; }
public ITaskbarSettings Taskbar { get; private set; }
public Settings(BrowserSettings browser, KeyboardSettings keyboard, LoggingSettings logging, MouseSettings mouse, TaskbarSettings taskbar)
public Settings(BrowserSettings browser, KeyboardSettings keyboard, MouseSettings mouse, TaskbarSettings taskbar)
{
Browser = browser;
Keyboard = keyboard;
Logging = logging;
Mouse = mouse;
Taskbar = taskbar;
}

View file

@ -7,8 +7,6 @@
*/
using System;
using System.IO;
using System.Reflection;
using SafeExamBrowser.Contracts.Configuration.Settings;
namespace SafeExamBrowser.Configuration.Settings
@ -25,26 +23,11 @@ namespace SafeExamBrowser.Configuration.Settings
{
var browser = new BrowserSettings();
var keyboard = new KeyboardSettings();
var logging = new LoggingSettings();
var mouse = new MouseSettings();
var taskbar = new TaskbarSettings();
var settings = new Settings(browser, keyboard, logging, mouse, taskbar);
var executable = Assembly.GetEntryAssembly();
var startTime = DateTime.Now;
var logFolderName = "Logs";
var logFilePrefix = startTime.ToString("yyyy-MM-dd\\_HH\\hmm\\mss\\s");
var settings = new Settings(browser, keyboard, mouse, taskbar);
settings.AppDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), nameof(SafeExamBrowser));
settings.ProgramCopyright = executable.GetCustomAttribute<AssemblyCopyrightAttribute>().Copyright;
settings.ProgramTitle = executable.GetCustomAttribute<AssemblyTitleAttribute>().Title;
settings.ProgramVersion = executable.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;
browser.CachePath = Path.Combine(settings.AppDataFolder, "Cache");
logging.ApplicationStartTime = DateTime.Now;
logging.BrowserLogFile = Path.Combine(settings.AppDataFolder, logFolderName, $"{logFilePrefix}_Browser.txt");
logging.ClientLogFile = Path.Combine(settings.AppDataFolder, logFolderName, $"{logFilePrefix}_Client.txt");
logging.RuntimeLogFile = Path.Combine(settings.AppDataFolder, logFolderName, $"{logFilePrefix}_Runtime.txt");
// TODO
return settings;
}

View file

@ -8,15 +8,25 @@
using System;
namespace SafeExamBrowser.Contracts.Configuration.Settings
namespace SafeExamBrowser.Contracts.Configuration
{
public interface ILoggingSettings
public interface IRuntimeInfo
{
/// <summary>
/// The path of the application data folder.
/// </summary>
string AppDataFolder { get; }
/// <summary>
/// The point in time when the application was started.
/// </summary>
DateTime ApplicationStartTime { get; }
/// <summary>
/// The path where the browser cache is to be stored.
/// </summary>
string BrowserCachePath { get; }
/// <summary>
/// The file path under which the log of the browser component is to be stored.
/// </summary>
@ -27,6 +37,21 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings
/// </summary>
string ClientLogFile { get; }
/// <summary>
/// The copyright information for the application (i.e. the executing assembly).
/// </summary>
string ProgramCopyright { get; }
/// <summary>
/// The program title of the application (i.e. the executing assembly).
/// </summary>
string ProgramTitle { get; }
/// <summary>
/// The program version of the application (i.e. the executing assembly).
/// </summary>
string ProgramVersion { get; }
/// <summary>
/// The file path under which the log of the runtime component is to be stored.
/// </summary>

View file

@ -35,16 +35,6 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings
/// </summary>
bool AllowReloading { get; }
/// <summary>
/// The path where the browser cache is to be stored.
/// </summary>
string CachePath { get; }
/// <summary>
/// The file path under which the browser log is to be stored.
/// </summary>
string LogFile { get; }
/// <summary>
/// Determines whether the main browser window should be rendered in fullscreen mode, i.e. without window frame.
/// </summary>

View file

@ -10,11 +10,6 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings
{
public interface ISettings
{
/// <summary>
/// The path of the application data folder.
/// </summary>
string AppDataFolder { get; }
/// <summary>
/// All browser-related settings.
/// </summary>
@ -25,31 +20,11 @@ namespace SafeExamBrowser.Contracts.Configuration.Settings
/// </summary>
IKeyboardSettings Keyboard { get; }
/// <summary>
/// All logging-related settings.
/// </summary>
ILoggingSettings Logging { get; }
/// <summary>
/// All mouse-related settings.
/// </summary>
IMouseSettings Mouse { get; }
/// <summary>
/// The copyright information for the application (i.e. the executing assembly).
/// </summary>
string ProgramCopyright { get; }
/// <summary>
/// The program title of the application (i.e. the executing assembly).
/// </summary>
string ProgramTitle { get; }
/// <summary>
/// The program version of the application (i.e. the executing assembly).
/// </summary>
string ProgramVersion { get; }
/// <summary>
/// All taskbar-related settings.
/// </summary>

View file

@ -53,6 +53,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Behaviour\IApplicationController.cs" />
<Compile Include="Configuration\IRuntimeInfo.cs" />
<Compile Include="Runtime\IRuntimeController.cs" />
<Compile Include="Behaviour\INotificationController.cs" />
<Compile Include="Behaviour\IOperation.cs" />
@ -65,7 +66,6 @@
<Compile Include="Configuration\OperatingSystem.cs" />
<Compile Include="Configuration\Settings\IBrowserSettings.cs" />
<Compile Include="Configuration\Settings\IKeyboardSettings.cs" />
<Compile Include="Configuration\Settings\ILoggingSettings.cs" />
<Compile Include="Configuration\Settings\IMouseSettings.cs" />
<Compile Include="Configuration\Settings\ISettings.cs" />
<Compile Include="Behaviour\IShutdownController.cs" />

View file

@ -19,7 +19,7 @@ namespace SafeExamBrowser.Contracts.UserInterface
/// <summary>
/// Creates a new about window displaying information about the currently running application version.
/// </summary>
IWindow CreateAboutWindow(ISettings settings, IText text);
IWindow CreateAboutWindow(IRuntimeInfo runtimeInfo, IText text);
/// <summary>
/// Creates a taskbar button, initialized with the given application information.
@ -54,7 +54,7 @@ namespace SafeExamBrowser.Contracts.UserInterface
/// <summary>
/// Creates a new splash screen which runs on its own thread.
/// </summary>
ISplashScreen CreateSplashScreen(ISettings settings, IText text);
ISplashScreen CreateSplashScreen(IRuntimeInfo runtimeInfo, IText text);
/// <summary>
/// Creates a system control which allows to change the wireless network connection of the computer.

View file

@ -11,7 +11,7 @@ using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SafeExamBrowser.Contracts.Behaviour;
using SafeExamBrowser.Contracts.Configuration.Settings;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.I18n;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Contracts.UserInterface;
@ -23,7 +23,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
public class ShutdownControllerTests
{
private Mock<ILogger> loggerMock;
private Mock<ISettings> settingsMock;
private Mock<IRuntimeInfo> runtimeInfoMock;
private Mock<IText> textMock;
private Mock<IUserInterfaceFactory> uiFactoryMock;
@ -33,13 +33,13 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
public void Initialize()
{
loggerMock = new Mock<ILogger>();
settingsMock = new Mock<ISettings>();
runtimeInfoMock = new Mock<IRuntimeInfo>();
textMock = new Mock<IText>();
uiFactoryMock = new Mock<IUserInterfaceFactory>();
uiFactoryMock.Setup(f => f.CreateSplashScreen(settingsMock.Object, textMock.Object)).Returns(new Mock<ISplashScreen>().Object);
uiFactoryMock.Setup(f => f.CreateSplashScreen(runtimeInfoMock.Object, textMock.Object)).Returns(new Mock<ISplashScreen>().Object);
sut = new ShutdownController(loggerMock.Object, settingsMock.Object, textMock.Object, uiFactoryMock.Object);
sut = new ShutdownController(loggerMock.Object, runtimeInfoMock.Object, textMock.Object, uiFactoryMock.Object);
}
[TestMethod]
@ -117,7 +117,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
[TestMethod]
public void MustNotFailInCaseOfUnexpectedError()
{
uiFactoryMock.Setup(l => l.CreateSplashScreen(It.IsAny<ISettings>(), It.IsAny<IText>())).Throws(new Exception());
uiFactoryMock.Setup(l => l.CreateSplashScreen(It.IsAny<IRuntimeInfo>(), It.IsAny<IText>())).Throws(new Exception());
sut.FinalizeApplication(new Queue<IOperation>());
}
}

View file

@ -24,7 +24,7 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
public class StartupControllerTests
{
private Mock<ILogger> loggerMock;
private Mock<ISettings> settingsMock;
private Mock<IRuntimeInfo> runtimeInfoMock;
private Mock<ISystemInfo> systemInfoMock;
private Mock<IText> textMock;
private Mock<IUserInterfaceFactory> uiFactoryMock;
@ -35,14 +35,14 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
public void Initialize()
{
loggerMock = new Mock<ILogger>();
settingsMock = new Mock<ISettings>();
runtimeInfoMock = new Mock<IRuntimeInfo>();
systemInfoMock = new Mock<ISystemInfo>();
textMock = new Mock<IText>();
uiFactoryMock = new Mock<IUserInterfaceFactory>();
uiFactoryMock.Setup(f => f.CreateSplashScreen(settingsMock.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, settingsMock.Object, systemInfoMock.Object, textMock.Object, uiFactoryMock.Object);
sut = new StartupController(loggerMock.Object, runtimeInfoMock.Object, systemInfoMock.Object, textMock.Object, uiFactoryMock.Object);
}
[TestMethod]

View file

@ -8,7 +8,7 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SafeExamBrowser.Contracts.Configuration.Settings;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.I18n;
using SafeExamBrowser.Contracts.UserInterface;
using SafeExamBrowser.Core.Notifications;
@ -18,14 +18,14 @@ namespace SafeExamBrowser.Core.UnitTests.Notifications
[TestClass]
public class AboutNotificationControllerTests
{
private Mock<ISettings> settingsMock;
private Mock<IRuntimeInfo> runtimeInfoMock;
private Mock<IText> textMock;
private Mock<IUserInterfaceFactory> uiFactoryMock;
[TestInitialize]
public void Initialize()
{
settingsMock = new Mock<ISettings>();
runtimeInfoMock = new Mock<IRuntimeInfo>();
textMock = new Mock<IText>();
uiFactoryMock = new Mock<IUserInterfaceFactory>();
}
@ -35,9 +35,9 @@ namespace SafeExamBrowser.Core.UnitTests.Notifications
{
var button = new NotificationButtonMock();
var window = new Mock<IWindow>();
var sut = new AboutNotificationController(settingsMock.Object, textMock.Object, uiFactoryMock.Object);
var sut = new AboutNotificationController(runtimeInfoMock.Object, textMock.Object, uiFactoryMock.Object);
uiFactoryMock.Setup(u => u.CreateAboutWindow(It.IsAny<ISettings>(), It.IsAny<IText>())).Returns(window.Object);
uiFactoryMock.Setup(u => u.CreateAboutWindow(It.IsAny<IRuntimeInfo>(), It.IsAny<IText>())).Returns(window.Object);
sut.RegisterNotification(button);
button.Click();
sut.Terminate();
@ -50,9 +50,9 @@ namespace SafeExamBrowser.Core.UnitTests.Notifications
{
var button = new NotificationButtonMock();
var window = new Mock<IWindow>();
var sut = new AboutNotificationController(settingsMock.Object, textMock.Object, uiFactoryMock.Object);
var sut = new AboutNotificationController(runtimeInfoMock.Object, textMock.Object, uiFactoryMock.Object);
uiFactoryMock.Setup(u => u.CreateAboutWindow(It.IsAny<ISettings>(), It.IsAny<IText>())).Returns(window.Object);
uiFactoryMock.Setup(u => u.CreateAboutWindow(It.IsAny<IRuntimeInfo>(), It.IsAny<IText>())).Returns(window.Object);
sut.RegisterNotification(button);
button.Click();
button.Click();
@ -60,7 +60,7 @@ namespace SafeExamBrowser.Core.UnitTests.Notifications
button.Click();
button.Click();
uiFactoryMock.Verify(u => u.CreateAboutWindow(It.IsAny<ISettings>(), It.IsAny<IText>()), Times.Once);
uiFactoryMock.Verify(u => u.CreateAboutWindow(It.IsAny<IRuntimeInfo>(), It.IsAny<IText>()), Times.Once);
window.Verify(u => u.Show(), Times.Once);
window.Verify(u => u.BringToForeground(), Times.Exactly(4));
}
@ -69,7 +69,7 @@ namespace SafeExamBrowser.Core.UnitTests.Notifications
public void MustSubscribeToClickEvent()
{
var button = new NotificationButtonMock();
var sut = new AboutNotificationController(settingsMock.Object, textMock.Object, uiFactoryMock.Object);
var sut = new AboutNotificationController(runtimeInfoMock.Object, textMock.Object, uiFactoryMock.Object);
sut.RegisterNotification(button);

View file

@ -9,6 +9,7 @@
using System;
using System.Collections.Generic;
using SafeExamBrowser.Contracts.Behaviour;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Configuration.Settings;
using SafeExamBrowser.Contracts.I18n;
using SafeExamBrowser.Contracts.Logging;
@ -19,15 +20,15 @@ namespace SafeExamBrowser.Core.Behaviour
public class ShutdownController : IShutdownController
{
private ILogger logger;
private ISettings settings;
private IRuntimeInfo runtimeInfo;
private ISplashScreen splashScreen;
private IText text;
private IUserInterfaceFactory uiFactory;
public ShutdownController(ILogger logger, ISettings settings, IText text, IUserInterfaceFactory uiFactory)
public ShutdownController(ILogger logger, IRuntimeInfo runtimeInfo, IText text, IUserInterfaceFactory uiFactory)
{
this.logger = logger;
this.settings = settings;
this.runtimeInfo = runtimeInfo;
this.text = text;
this.uiFactory = uiFactory;
}
@ -69,7 +70,7 @@ namespace SafeExamBrowser.Core.Behaviour
logger.Log(string.Empty);
logger.Info("--- Initiating shutdown procedure ---");
splashScreen = uiFactory.CreateSplashScreen(settings, text);
splashScreen = uiFactory.CreateSplashScreen(runtimeInfo, text);
splashScreen.SetIndeterminate();
splashScreen.UpdateText(TextKey.SplashScreen_ShutdownProcedure);
splashScreen.InvokeShow();

View file

@ -21,7 +21,7 @@ namespace SafeExamBrowser.Core.Behaviour
public class StartupController : IStartupController
{
private ILogger logger;
private ISettings settings;
private IRuntimeInfo runtimeInfo;
private ISplashScreen splashScreen;
private ISystemInfo systemInfo;
private IText text;
@ -29,10 +29,10 @@ namespace SafeExamBrowser.Core.Behaviour
private Stack<IOperation> stack = new Stack<IOperation>();
public StartupController(ILogger logger, ISettings settings, ISystemInfo systemInfo, IText text, IUserInterfaceFactory uiFactory)
public StartupController(ILogger logger, IRuntimeInfo runtimeInfo, ISystemInfo systemInfo, IText text, IUserInterfaceFactory uiFactory)
{
this.logger = logger;
this.settings = settings;
this.runtimeInfo = runtimeInfo;
this.systemInfo = systemInfo;
this.text = text;
this.uiFactory = uiFactory;
@ -92,8 +92,8 @@ namespace SafeExamBrowser.Core.Behaviour
private void Initialize(int operationCount)
{
var titleLine = $"/* {settings.ProgramTitle}, Version {settings.ProgramVersion}{Environment.NewLine}";
var copyrightLine = $"/* {settings.ProgramCopyright}{Environment.NewLine}";
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.";
@ -105,7 +105,7 @@ namespace SafeExamBrowser.Core.Behaviour
logger.Info("--- Initiating startup procedure ---");
splashScreen = uiFactory.CreateSplashScreen(settings, text);
splashScreen = uiFactory.CreateSplashScreen(runtimeInfo, text);
splashScreen.SetMaxProgress(operationCount);
splashScreen.UpdateText(TextKey.SplashScreen_StartupProcedure);
splashScreen.InvokeShow();

View file

@ -24,6 +24,16 @@ namespace SafeExamBrowser.Core.Logging
this.formatter = formatter;
}
public void Initialize()
{
var logFolder = Path.GetDirectoryName(filePath);
if (!Directory.Exists(logFolder))
{
Directory.CreateDirectory(logFolder);
}
}
public void Notify(ILogContent content)
{
lock (@lock)

View file

@ -7,6 +7,7 @@
*/
using SafeExamBrowser.Contracts.Behaviour;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Configuration.Settings;
using SafeExamBrowser.Contracts.I18n;
using SafeExamBrowser.Contracts.UserInterface;
@ -17,14 +18,14 @@ namespace SafeExamBrowser.Core.Notifications
public class AboutNotificationController : INotificationController
{
private INotificationButton notification;
private ISettings settings;
private IRuntimeInfo runtimeInfo;
private IText text;
private IUserInterfaceFactory uiFactory;
private IWindow window;
public AboutNotificationController(ISettings settings, IText text, IUserInterfaceFactory uiFactory)
public AboutNotificationController(IRuntimeInfo runtimeInfo, IText text, IUserInterfaceFactory uiFactory)
{
this.settings = settings;
this.runtimeInfo = runtimeInfo;
this.text = text;
this.uiFactory = uiFactory;
}
@ -45,7 +46,7 @@ namespace SafeExamBrowser.Core.Notifications
{
if (window == null)
{
window = uiFactory.CreateAboutWindow(settings, text);
window = uiFactory.CreateAboutWindow(runtimeInfo, text);
window.Closing += () => window = null;
window.Show();

View file

@ -8,7 +8,7 @@
using System.Windows;
using System.Windows.Documents;
using SafeExamBrowser.Contracts.Configuration.Settings;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.I18n;
using SafeExamBrowser.Contracts.UserInterface;
@ -16,7 +16,7 @@ namespace SafeExamBrowser.UserInterface.Classic
{
public partial class AboutWindow : Window, IWindow
{
private ISettings settings;
private IRuntimeInfo runtimeInfo;
private IText text;
private WindowClosingEventHandler closing;
@ -26,9 +26,9 @@ namespace SafeExamBrowser.UserInterface.Classic
remove { closing -= value; }
}
public AboutWindow(ISettings settings, IText text)
public AboutWindow(IRuntimeInfo runtimeInfo, IText text)
{
this.settings = settings;
this.runtimeInfo = runtimeInfo;
this.text = text;
InitializeComponent();
@ -43,10 +43,10 @@ namespace SafeExamBrowser.UserInterface.Classic
private void InitializeAboutWindow()
{
Closing += (o, args) => closing?.Invoke();
VersionInfo.Inlines.Add(new Run($"{text.Get(TextKey.Version)} {settings.ProgramVersion}") { FontStyle = FontStyles.Italic });
VersionInfo.Inlines.Add(new Run($"{text.Get(TextKey.Version)} {runtimeInfo.ProgramVersion}") { FontStyle = FontStyles.Italic });
VersionInfo.Inlines.Add(new LineBreak());
VersionInfo.Inlines.Add(new LineBreak());
VersionInfo.Inlines.Add(new Run(settings.ProgramCopyright) { FontSize = 10 });
VersionInfo.Inlines.Add(new Run(runtimeInfo.ProgramCopyright) { FontSize = 10 });
}
}
}

View file

@ -8,7 +8,7 @@
using System.Windows;
using System.Windows.Documents;
using SafeExamBrowser.Contracts.Configuration.Settings;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.I18n;
using SafeExamBrowser.Contracts.UserInterface;
using SafeExamBrowser.UserInterface.Classic.ViewModels;
@ -18,12 +18,12 @@ namespace SafeExamBrowser.UserInterface.Classic
public partial class SplashScreen : Window, ISplashScreen
{
private SplashScreenViewModel model = new SplashScreenViewModel();
private ISettings settings;
private IRuntimeInfo runtimeInfo;
private IText text;
public SplashScreen(ISettings settings, IText text)
public SplashScreen(IRuntimeInfo runtimeInfo, IText text)
{
this.settings = settings;
this.runtimeInfo = runtimeInfo;
this.text = text;
InitializeComponent();
@ -73,10 +73,10 @@ namespace SafeExamBrowser.UserInterface.Classic
private void InitializeSplashScreen()
{
InfoTextBlock.Inlines.Add(new Run($"Version {settings.ProgramVersion}") { FontStyle = FontStyles.Italic });
InfoTextBlock.Inlines.Add(new Run($"Version {runtimeInfo.ProgramVersion}") { FontStyle = FontStyles.Italic });
InfoTextBlock.Inlines.Add(new LineBreak());
InfoTextBlock.Inlines.Add(new LineBreak());
InfoTextBlock.Inlines.Add(new Run(settings.ProgramCopyright) { FontSize = 10 });
InfoTextBlock.Inlines.Add(new Run(runtimeInfo.ProgramCopyright) { FontSize = 10 });
StatusTextBlock.DataContext = model;
ProgressBar.DataContext = model;

View file

@ -20,9 +20,9 @@ namespace SafeExamBrowser.UserInterface.Classic
{
public class UserInterfaceFactory : IUserInterfaceFactory
{
public IWindow CreateAboutWindow(ISettings settings, IText text)
public IWindow CreateAboutWindow(IRuntimeInfo runtimeInfo, IText text)
{
return new AboutWindow(settings, text);
return new AboutWindow(runtimeInfo, text);
}
public IApplicationButton CreateApplicationButton(IApplicationInfo info)
@ -75,13 +75,13 @@ namespace SafeExamBrowser.UserInterface.Classic
return new PowerSupplyControl();
}
public ISplashScreen CreateSplashScreen(ISettings settings, IText text)
public ISplashScreen CreateSplashScreen(IRuntimeInfo runtimeInfo, IText text)
{
SplashScreen splashScreen = null;
var splashReadyEvent = new AutoResetEvent(false);
var splashScreenThread = new Thread(() =>
{
splashScreen = new SplashScreen(settings, text);
splashScreen = new SplashScreen(runtimeInfo, text);
splashScreen.Closed += (o, args) => splashScreen.Dispatcher.InvokeShutdown();
splashScreen.Show();

View file

@ -8,7 +8,7 @@
using System.Windows;
using System.Windows.Documents;
using SafeExamBrowser.Contracts.Configuration.Settings;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.I18n;
using SafeExamBrowser.Contracts.UserInterface;
@ -16,7 +16,7 @@ namespace SafeExamBrowser.UserInterface.Windows10
{
public partial class AboutWindow : Window, IWindow
{
private ISettings settings;
private IRuntimeInfo runtimeInfo;
private IText text;
private WindowClosingEventHandler closing;
@ -26,9 +26,9 @@ namespace SafeExamBrowser.UserInterface.Windows10
remove { closing -= value; }
}
public AboutWindow(ISettings settings, IText text)
public AboutWindow(IRuntimeInfo runtimeInfo, IText text)
{
this.settings = settings;
this.runtimeInfo = runtimeInfo;
this.text = text;
InitializeComponent();
@ -43,10 +43,10 @@ namespace SafeExamBrowser.UserInterface.Windows10
private void InitializeAboutWindow()
{
Closing += (o, args) => closing?.Invoke();
VersionInfo.Inlines.Add(new Run($"{text.Get(TextKey.Version)} {settings.ProgramVersion}") { FontStyle = FontStyles.Italic });
VersionInfo.Inlines.Add(new Run($"{text.Get(TextKey.Version)} {runtimeInfo.ProgramVersion}") { FontStyle = FontStyles.Italic });
VersionInfo.Inlines.Add(new LineBreak());
VersionInfo.Inlines.Add(new LineBreak());
VersionInfo.Inlines.Add(new Run(settings.ProgramCopyright) { FontSize = 10 });
VersionInfo.Inlines.Add(new Run(runtimeInfo.ProgramCopyright) { FontSize = 10 });
}
}
}

View file

@ -8,7 +8,7 @@
using System.Windows;
using System.Windows.Documents;
using SafeExamBrowser.Contracts.Configuration.Settings;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.I18n;
using SafeExamBrowser.Contracts.UserInterface;
using SafeExamBrowser.UserInterface.Windows10.ViewModels;
@ -18,12 +18,12 @@ namespace SafeExamBrowser.UserInterface.Windows10
public partial class SplashScreen : Window, ISplashScreen
{
private SplashScreenViewModel model = new SplashScreenViewModel();
private ISettings settings;
private IRuntimeInfo runtimeInfo;
private IText text;
public SplashScreen(ISettings settings, IText text)
public SplashScreen(IRuntimeInfo runtimeInfo, IText text)
{
this.settings = settings;
this.runtimeInfo = runtimeInfo;
this.text = text;
InitializeComponent();
@ -73,10 +73,10 @@ namespace SafeExamBrowser.UserInterface.Windows10
private void InitializeSplashScreen()
{
InfoTextBlock.Inlines.Add(new Run($"Version {settings.ProgramVersion}") { FontStyle = FontStyles.Italic });
InfoTextBlock.Inlines.Add(new Run($"Version {runtimeInfo.ProgramVersion}") { FontStyle = FontStyles.Italic });
InfoTextBlock.Inlines.Add(new LineBreak());
InfoTextBlock.Inlines.Add(new LineBreak());
InfoTextBlock.Inlines.Add(new Run(settings.ProgramCopyright) { FontSize = 10 });
InfoTextBlock.Inlines.Add(new Run(runtimeInfo.ProgramCopyright) { FontSize = 10 });
StatusTextBlock.DataContext = model;
ProgressBar.DataContext = model;

View file

@ -20,9 +20,9 @@ namespace SafeExamBrowser.UserInterface.Windows10
{
public class UserInterfaceFactory : IUserInterfaceFactory
{
public IWindow CreateAboutWindow(ISettings settings, IText text)
public IWindow CreateAboutWindow(IRuntimeInfo runtimeInfo, IText text)
{
return new AboutWindow(settings, text);
return new AboutWindow(runtimeInfo, text);
}
public IApplicationButton CreateApplicationButton(IApplicationInfo info)
@ -76,13 +76,13 @@ namespace SafeExamBrowser.UserInterface.Windows10
return new PowerSupplyControl();
}
public ISplashScreen CreateSplashScreen(ISettings settings, IText text)
public ISplashScreen CreateSplashScreen(IRuntimeInfo runtimeInfo, IText text)
{
SplashScreen splashScreen = null;
var splashReadyEvent = new AutoResetEvent(false);
var splashScreenThread = new Thread(() =>
{
splashScreen = new SplashScreen(settings, text);
splashScreen = new SplashScreen(runtimeInfo, text);
splashScreen.Closed += (o, args) => splashScreen.Dispatcher.InvokeShutdown();
splashScreen.Show();

View file

@ -66,9 +66,9 @@ namespace SafeExamBrowser
if (success)
{
// TODO: Probably needs new window to display status of running application...
MainWindow = instances.SplashScreen;
MainWindow.Closing += MainWindow_Closing;
MainWindow.Show();
//MainWindow = instances.SplashScreen;
//MainWindow.Closing += MainWindow_Closing;
//MainWindow.Show();
}
else
{

View file

@ -7,18 +7,14 @@
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using SafeExamBrowser.Configuration;
using SafeExamBrowser.Configuration.Settings;
using SafeExamBrowser.Contracts.Behaviour;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Configuration.Settings;
using SafeExamBrowser.Contracts.I18n;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Contracts.Runtime;
using SafeExamBrowser.Contracts.UserInterface;
using SafeExamBrowser.Contracts.WindowsApi;
using SafeExamBrowser.Core.Behaviour;
using SafeExamBrowser.Core.Behaviour.Operations;
using SafeExamBrowser.Core.I18n;
@ -30,50 +26,60 @@ namespace SafeExamBrowser
{
internal class CompositionRoot
{
private ILogger logger;
private INativeMethods nativeMethods;
private IRuntimeController runtimeController;
private ISettings settings;
private ISystemInfo systemInfo;
private IText text;
private IUserInterfaceFactory uiFactory;
internal IShutdownController ShutdownController { get; private set; }
internal IStartupController StartupController { get; private set; }
internal Queue<IOperation> StartupOperations { get; private set; }
internal SplashScreen SplashScreen { get; private set; }
internal void BuildObjectGraph()
{
nativeMethods = new NativeMethods();
settings = new SettingsRepository().LoadDefaults();
systemInfo = new SystemInfo();
uiFactory = new UserInterfaceFactory();
var logger = new Logger();
var nativeMethods = new NativeMethods();
var runtimeInfo = new RuntimeInfo();
var systemInfo = new SystemInfo();
var uiFactory = new UserInterfaceFactory();
InitializeLogger();
Initialize(runtimeInfo);
Initialize(logger, runtimeInfo);
text = new Text(logger);
var text = new Text(logger);
var runtimeController = new RuntimeController(new ModuleLogger(logger, typeof(RuntimeController)));
runtimeController = new RuntimeController(new ModuleLogger(logger, typeof(RuntimeController)));
ShutdownController = new ShutdownController(logger, settings, text, uiFactory);
StartupController = new StartupController(logger, settings, systemInfo, text, uiFactory);
ShutdownController = new ShutdownController(logger, runtimeInfo, text, uiFactory);
StartupController = new StartupController(logger, runtimeInfo, systemInfo, text, uiFactory);
StartupOperations = new Queue<IOperation>();
StartupOperations.Enqueue(new I18nOperation(logger, text));
// TODO
//StartupOperations.Enqueue(new ConfigurationOperation());
//StartupOperations.Enqueue(new KioskModeOperation());
StartupOperations.Enqueue(new RuntimeControllerOperation(runtimeController, logger));
}
private void InitializeLogger()
private void Initialize(RuntimeInfo runtimeInfo)
{
var logFolder = Path.GetDirectoryName(settings.Logging.RuntimeLogFile);
var appDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), nameof(SafeExamBrowser));
var executable = Assembly.GetEntryAssembly();
var startTime = DateTime.Now;
var logFolder = Path.Combine(appDataFolder, "Logs");
var logFilePrefix = startTime.ToString("yyyy-MM-dd\\_HH\\hmm\\mss\\s");
if (!Directory.Exists(logFolder))
{
Directory.CreateDirectory(logFolder);
}
runtimeInfo.ApplicationStartTime = startTime;
runtimeInfo.AppDataFolder = appDataFolder;
runtimeInfo.BrowserCachePath = Path.Combine(appDataFolder, "Cache");
runtimeInfo.BrowserLogFile = Path.Combine(logFolder, $"{logFilePrefix}_Browser.txt");
runtimeInfo.ClientLogFile = Path.Combine(logFolder, $"{logFilePrefix}_Client.txt");
runtimeInfo.ProgramCopyright = executable.GetCustomAttribute<AssemblyCopyrightAttribute>().Copyright;
runtimeInfo.ProgramTitle = executable.GetCustomAttribute<AssemblyTitleAttribute>().Title;
runtimeInfo.ProgramVersion = executable.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;
runtimeInfo.RuntimeLogFile = Path.Combine(logFolder, $"{logFilePrefix}_Runtime.txt");
}
logger = new Logger();
logger.Subscribe(new LogFileWriter(new DefaultLogFormatter(), settings.Logging.RuntimeLogFile));
private void Initialize(ILogger logger, IRuntimeInfo runtimeInfo)
{
var logFileWriter = new LogFileWriter(new DefaultLogFormatter(), runtimeInfo.RuntimeLogFile);
logFileWriter.Initialize();
logger.Subscribe(logFileWriter);
}
}
}