Implemented basic display / sleep mode handling and added logging to taskbar.
This commit is contained in:
parent
49540af39d
commit
939bc7f79a
28 changed files with 436 additions and 174 deletions
|
@ -10,7 +10,7 @@ using System;
|
|||
using System.IO;
|
||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||
|
||||
namespace SafeExamBrowser.Configuration.Settings
|
||||
namespace SafeExamBrowser.Configuration
|
||||
{
|
||||
public class BrowserSettings : IBrowserSettings
|
||||
{
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||
|
||||
namespace SafeExamBrowser.Configuration.Settings
|
||||
namespace SafeExamBrowser.Configuration
|
||||
{
|
||||
public class KeyboardSettings : IKeyboardSettings
|
||||
{
|
|
@ -8,12 +8,12 @@
|
|||
|
||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||
|
||||
namespace SafeExamBrowser.Configuration.Settings
|
||||
namespace SafeExamBrowser.Configuration
|
||||
{
|
||||
public class MouseSettings : IMouseSettings
|
||||
{
|
||||
public bool AllowMiddleButton => false;
|
||||
|
||||
public bool AllowRightButton => false;
|
||||
public bool AllowRightButton => true;
|
||||
}
|
||||
}
|
|
@ -60,12 +60,10 @@
|
|||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Bounds.cs" />
|
||||
<Compile Include="Settings\BrowserSettings.cs" />
|
||||
<Compile Include="Settings\KeyboardSettings.cs" />
|
||||
<Compile Include="Settings\MouseSettings.cs" />
|
||||
<Compile Include="Settings\SettingsImpl.cs" />
|
||||
<Compile Include="WorkingArea.cs" />
|
||||
<Compile Include="BrowserSettings.cs" />
|
||||
<Compile Include="KeyboardSettings.cs" />
|
||||
<Compile Include="MouseSettings.cs" />
|
||||
<Compile Include="Settings.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using SafeExamBrowser.Configuration.Settings;
|
||||
using SafeExamBrowser.Contracts.Configuration.Settings;
|
||||
|
||||
namespace SafeExamBrowser.Configuration
|
||||
|
@ -17,11 +16,11 @@ namespace SafeExamBrowser.Configuration
|
|||
/// <remarks>
|
||||
/// TODO: Replace with proper implementation once configuration aspects are clear...
|
||||
/// </remarks>
|
||||
public class SettingsImpl : ISettings
|
||||
public class Settings : ISettings
|
||||
{
|
||||
private static readonly string LogFileDate = DateTime.Now.ToString("yyyy-MM-dd\\_HH\\hmm\\mss\\s");
|
||||
|
||||
public SettingsImpl()
|
||||
public Settings()
|
||||
{
|
||||
Browser = new BrowserSettings(this);
|
||||
Keyboard = new KeyboardSettings();
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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.Windows.Forms;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.UserInterface;
|
||||
using SafeExamBrowser.Contracts.WindowsApi;
|
||||
|
||||
namespace SafeExamBrowser.Configuration
|
||||
{
|
||||
public class WorkingArea : IWorkingArea
|
||||
{
|
||||
private ILogger logger;
|
||||
private INativeMethods nativeMethods;
|
||||
private IBounds originalWorkingArea;
|
||||
|
||||
public WorkingArea(ILogger logger, INativeMethods nativeMethods)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.nativeMethods = nativeMethods;
|
||||
}
|
||||
|
||||
public void InitializeFor(ITaskbar taskbar)
|
||||
{
|
||||
originalWorkingArea = nativeMethods.GetWorkingArea();
|
||||
|
||||
LogWorkingArea("Saved original working area", originalWorkingArea);
|
||||
|
||||
var area = new Bounds
|
||||
{
|
||||
Left = 0,
|
||||
Top = 0,
|
||||
Right = Screen.PrimaryScreen.Bounds.Width,
|
||||
Bottom = Screen.PrimaryScreen.Bounds.Height - taskbar.GetAbsoluteHeight()
|
||||
};
|
||||
|
||||
LogWorkingArea("Trying to set new working area", area);
|
||||
nativeMethods.SetWorkingArea(area);
|
||||
LogWorkingArea("Working area is now set to", nativeMethods.GetWorkingArea());
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
if (originalWorkingArea != null)
|
||||
{
|
||||
nativeMethods.SetWorkingArea(originalWorkingArea);
|
||||
LogWorkingArea("Restored original working area", originalWorkingArea);
|
||||
}
|
||||
}
|
||||
|
||||
private void LogWorkingArea(string message, IBounds area)
|
||||
{
|
||||
logger.Info($"{message}: Left = {area.Left}, Top = {area.Top}, Right = {area.Right}, Bottom = {area.Bottom}.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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 SafeExamBrowser.Contracts.UserInterface;
|
||||
|
||||
namespace SafeExamBrowser.Contracts.Configuration
|
||||
{
|
||||
public interface IWorkingArea
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the Windows working area to accommodate to the taskbar's dimensions.
|
||||
/// </summary>
|
||||
void InitializeFor(ITaskbar taskbar);
|
||||
|
||||
/// <summary>
|
||||
/// Resets the Windows working area to its previous (initial) state.
|
||||
/// </summary>
|
||||
void Reset();
|
||||
}
|
||||
}
|
41
SafeExamBrowser.Contracts/Monitoring/IDisplayMonitor.cs
Normal file
41
SafeExamBrowser.Contracts/Monitoring/IDisplayMonitor.cs
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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/.
|
||||
*/
|
||||
|
||||
namespace SafeExamBrowser.Contracts.Monitoring
|
||||
{
|
||||
public delegate void DisplayChangedEventHandler();
|
||||
|
||||
public interface IDisplayMonitor
|
||||
{
|
||||
/// <summary>
|
||||
/// Event fired when the primary display or its settings have changed.
|
||||
/// </summary>
|
||||
event DisplayChangedEventHandler DisplayChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Sets the desktop working area to accommodate to the taskbar's height, removes the configured wallpaper (if possible) and
|
||||
/// prevents the computer from entering sleep mode or turning its display(s) off.
|
||||
/// </summary>
|
||||
void InitializePrimaryDisplay(int taskbarHeight);
|
||||
|
||||
/// <summary>
|
||||
/// Resets the desktop working area and wallpaper to their previous (initial) state.
|
||||
/// </summary>
|
||||
void ResetPrimaryDisplay();
|
||||
|
||||
/// <summary>
|
||||
/// Starts monitoring for display changes, i.e. display changes will trigger the <c>DisplaySettingsChanged</c> event.
|
||||
/// </summary>
|
||||
void StartMonitoringDisplayChanges();
|
||||
|
||||
/// <summary>
|
||||
/// Stops monitoring for display changes.
|
||||
/// </summary>
|
||||
void StopMonitoringDisplayChanges();
|
||||
}
|
||||
}
|
|
@ -72,7 +72,6 @@
|
|||
<Compile Include="Configuration\Settings\ISettings.cs" />
|
||||
<Compile Include="Behaviour\IShutdownController.cs" />
|
||||
<Compile Include="Behaviour\IStartupController.cs" />
|
||||
<Compile Include="Configuration\IWorkingArea.cs" />
|
||||
<Compile Include="I18n\IText.cs" />
|
||||
<Compile Include="I18n\TextKey.cs" />
|
||||
<Compile Include="Logging\ILogContent.cs" />
|
||||
|
@ -83,6 +82,7 @@
|
|||
<Compile Include="Logging\ILogText.cs" />
|
||||
<Compile Include="Logging\IThreadInfo.cs" />
|
||||
<Compile Include="Logging\LogLevel.cs" />
|
||||
<Compile Include="Monitoring\IDisplayMonitor.cs" />
|
||||
<Compile Include="Monitoring\IKeyboardInterceptor.cs" />
|
||||
<Compile Include="Monitoring\IMouseInterceptor.cs" />
|
||||
<Compile Include="Monitoring\IProcessMonitor.cs" />
|
||||
|
|
|
@ -38,6 +38,11 @@ namespace SafeExamBrowser.Contracts.WindowsApi
|
|||
/// </exception>
|
||||
void DeregisterSystemEvent(IntPtr handle);
|
||||
|
||||
/// <summary>
|
||||
/// Prevents Windows from entering sleep mode and keeps all displays powered on.
|
||||
/// </summary>
|
||||
void DisableSleep();
|
||||
|
||||
/// <summary>
|
||||
/// Empties the clipboard.
|
||||
/// </summary>
|
||||
|
@ -72,8 +77,15 @@ namespace SafeExamBrowser.Contracts.WindowsApi
|
|||
uint GetShellProcessId();
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the title of the specified window, or an empty string, if the
|
||||
/// given window does not have a title.
|
||||
/// Retrieves the path of the currently configured wallpaper image, or an empty string, if there is no wallpaper set.
|
||||
/// </summary>
|
||||
/// <exception cref="System.ComponentModel.Win32Exception">
|
||||
/// If the wallpaper path could not be retrieved.
|
||||
/// </exception>
|
||||
string GetWallpaperPath();
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the title of the specified window, or an empty string, if the given window does not have a title.
|
||||
/// </summary>
|
||||
string GetWindowTitle(IntPtr window);
|
||||
|
||||
|
@ -125,6 +137,14 @@ namespace SafeExamBrowser.Contracts.WindowsApi
|
|||
/// </summary>
|
||||
IntPtr RegisterSystemCaptureStartEvent(Action<IntPtr> callback);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the currently configured desktop wallpaper.
|
||||
/// </summary>
|
||||
/// <exception cref="System.ComponentModel.Win32Exception">
|
||||
/// If the wallpaper could not be removed.
|
||||
/// </exception>
|
||||
void RemoveWallpaper();
|
||||
|
||||
/// <summary>
|
||||
/// Restores the specified window to its original size and position.
|
||||
/// </summary>
|
||||
|
@ -135,6 +155,14 @@ namespace SafeExamBrowser.Contracts.WindowsApi
|
|||
/// </summary>
|
||||
void SendCloseMessageTo(IntPtr window);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the wallpaper to the image located at the specified file path.
|
||||
/// </summary>
|
||||
/// <exception cref="System.ComponentModel.Win32Exception">
|
||||
/// If the wallpaper could not be set.
|
||||
/// </exception>
|
||||
void SetWallpaper(string filePath);
|
||||
|
||||
/// <summary>
|
||||
/// Sets the working area of the primary screen according to the given dimensions.
|
||||
/// </summary>
|
||||
|
|
|
@ -10,7 +10,6 @@ using System;
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using SafeExamBrowser.Contracts.Behaviour;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.Monitoring;
|
||||
using SafeExamBrowser.Contracts.UserInterface;
|
||||
|
@ -21,33 +20,52 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
|
|||
[TestClass]
|
||||
public class RuntimeControllerTests
|
||||
{
|
||||
private Mock<IDisplayMonitor> displayMonitorMock;
|
||||
private Mock<ILogger> loggerMock;
|
||||
private Mock<IProcessMonitor> processMonitorMock;
|
||||
private Mock<ITaskbar> taskbarMock;
|
||||
private Mock<IWindowMonitor> windowMonitorMock;
|
||||
private Mock<IWorkingArea> workingAreaMock;
|
||||
|
||||
private IRuntimeController sut;
|
||||
|
||||
[TestInitialize]
|
||||
public void Initialize()
|
||||
{
|
||||
displayMonitorMock = new Mock<IDisplayMonitor>();
|
||||
loggerMock = new Mock<ILogger>();
|
||||
processMonitorMock = new Mock<IProcessMonitor>();
|
||||
taskbarMock = new Mock<ITaskbar>();
|
||||
windowMonitorMock= new Mock<IWindowMonitor>();
|
||||
workingAreaMock = new Mock<IWorkingArea>();
|
||||
|
||||
sut = new RuntimeController(
|
||||
displayMonitorMock.Object,
|
||||
loggerMock.Object,
|
||||
processMonitorMock.Object,
|
||||
taskbarMock.Object,
|
||||
windowMonitorMock.Object,
|
||||
workingAreaMock.Object);
|
||||
windowMonitorMock.Object);
|
||||
|
||||
sut.Start();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustHandleDisplayChangeCorrectly()
|
||||
{
|
||||
var order = 0;
|
||||
var workingArea = 0;
|
||||
var taskbar = 0;
|
||||
|
||||
displayMonitorMock.Setup(w => w.InitializePrimaryDisplay(taskbarMock.Object.GetAbsoluteHeight())).Callback(() => workingArea = ++order);
|
||||
taskbarMock.Setup(t => t.InitializeBounds()).Callback(() => taskbar = ++order);
|
||||
|
||||
displayMonitorMock.Raise(d => d.DisplayChanged += null);
|
||||
|
||||
displayMonitorMock.Verify(w => w.InitializePrimaryDisplay(taskbarMock.Object.GetAbsoluteHeight()), Times.Once);
|
||||
taskbarMock.Verify(t => t.InitializeBounds(), Times.Once);
|
||||
|
||||
Assert.IsTrue(workingArea == 1);
|
||||
Assert.IsTrue(taskbar == 2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void MustHandleExplorerStartCorrectly()
|
||||
{
|
||||
|
@ -57,13 +75,13 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour
|
|||
var taskbar = 0;
|
||||
|
||||
processMonitorMock.Setup(p => p.CloseExplorerShell()).Callback(() => processManager = ++order);
|
||||
workingAreaMock.Setup(w => w.InitializeFor(taskbarMock.Object)).Callback(() => workingArea = ++order);
|
||||
displayMonitorMock.Setup(w => w.InitializePrimaryDisplay(taskbarMock.Object.GetAbsoluteHeight())).Callback(() => workingArea = ++order);
|
||||
taskbarMock.Setup(t => t.InitializeBounds()).Callback(() => taskbar = ++order);
|
||||
|
||||
processMonitorMock.Raise(p => p.ExplorerStarted += null);
|
||||
|
||||
processMonitorMock.Verify(p => p.CloseExplorerShell(), Times.Once);
|
||||
workingAreaMock.Verify(w => w.InitializeFor(taskbarMock.Object), Times.Once);
|
||||
displayMonitorMock.Verify(w => w.InitializePrimaryDisplay(taskbarMock.Object.GetAbsoluteHeight()), Times.Once);
|
||||
taskbarMock.Verify(t => t.InitializeBounds(), Times.Once);
|
||||
|
||||
Assert.IsTrue(processManager == 1);
|
||||
|
|
|
@ -7,26 +7,26 @@
|
|||
*/
|
||||
|
||||
using SafeExamBrowser.Contracts.Behaviour;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.I18n;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.Monitoring;
|
||||
using SafeExamBrowser.Contracts.UserInterface;
|
||||
|
||||
namespace SafeExamBrowser.Core.Behaviour.Operations
|
||||
{
|
||||
public class WorkingAreaOperation : IOperation
|
||||
public class DisplayMonitorOperation : IOperation
|
||||
{
|
||||
private IDisplayMonitor displayMonitor;
|
||||
private ILogger logger;
|
||||
private ITaskbar taskbar;
|
||||
private IWorkingArea workingArea;
|
||||
|
||||
public ISplashScreen SplashScreen { private get; set; }
|
||||
|
||||
public WorkingAreaOperation(ILogger logger, ITaskbar taskbar, IWorkingArea workingArea)
|
||||
public DisplayMonitorOperation(IDisplayMonitor displayMonitor, ILogger logger, ITaskbar taskbar)
|
||||
{
|
||||
this.displayMonitor = displayMonitor;
|
||||
this.logger = logger;
|
||||
this.taskbar = taskbar;
|
||||
this.workingArea = workingArea;
|
||||
}
|
||||
|
||||
public void Perform()
|
||||
|
@ -34,10 +34,8 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
|||
logger.Info("Initializing working area...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_InitializeWorkingArea);
|
||||
|
||||
// TODO
|
||||
// - Emptying clipboard
|
||||
|
||||
workingArea.InitializeFor(taskbar);
|
||||
displayMonitor.InitializePrimaryDisplay(taskbar.GetAbsoluteHeight());
|
||||
displayMonitor.StartMonitoringDisplayChanges();
|
||||
}
|
||||
|
||||
public void Revert()
|
||||
|
@ -45,10 +43,8 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
|
|||
logger.Info("Restoring working area...");
|
||||
SplashScreen.UpdateText(TextKey.SplashScreen_RestoreWorkingArea);
|
||||
|
||||
// TODO
|
||||
// - Emptying clipboard
|
||||
|
||||
workingArea.Reset();
|
||||
displayMonitor.StopMonitoringDisplayChanges();
|
||||
displayMonitor.ResetPrimaryDisplay();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
using System;
|
||||
using SafeExamBrowser.Contracts.Behaviour;
|
||||
using SafeExamBrowser.Contracts.Configuration;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.Monitoring;
|
||||
using SafeExamBrowser.Contracts.UserInterface;
|
||||
|
@ -17,28 +16,29 @@ namespace SafeExamBrowser.Core.Behaviour
|
|||
{
|
||||
public class RuntimeController : IRuntimeController
|
||||
{
|
||||
private IDisplayMonitor displayMonitor;
|
||||
private ILogger logger;
|
||||
private IProcessMonitor processMonitor;
|
||||
private ITaskbar taskbar;
|
||||
private IWindowMonitor windowMonitor;
|
||||
private IWorkingArea workingArea;
|
||||
|
||||
public RuntimeController(
|
||||
IDisplayMonitor displayMonitor,
|
||||
ILogger logger,
|
||||
IProcessMonitor processMonitor,
|
||||
ITaskbar taskbar,
|
||||
IWindowMonitor windowMonitor,
|
||||
IWorkingArea workingArea)
|
||||
IWindowMonitor windowMonitor)
|
||||
{
|
||||
this.displayMonitor = displayMonitor;
|
||||
this.logger = logger;
|
||||
this.processMonitor = processMonitor;
|
||||
this.taskbar = taskbar;
|
||||
this.windowMonitor = windowMonitor;
|
||||
this.workingArea = workingArea;
|
||||
}
|
||||
|
||||
public void Start()
|
||||
{
|
||||
displayMonitor.DisplayChanged += DisplayMonitor_DisplaySettingsChanged;
|
||||
processMonitor.ExplorerStarted += ProcessMonitor_ExplorerStarted;
|
||||
windowMonitor.WindowChanged += WindowMonitor_WindowChanged;
|
||||
}
|
||||
|
@ -49,12 +49,21 @@ namespace SafeExamBrowser.Core.Behaviour
|
|||
windowMonitor.WindowChanged -= WindowMonitor_WindowChanged;
|
||||
}
|
||||
|
||||
private void DisplayMonitor_DisplaySettingsChanged()
|
||||
{
|
||||
logger.Info("Reinitializing working area...");
|
||||
displayMonitor.InitializePrimaryDisplay(taskbar.GetAbsoluteHeight());
|
||||
logger.Info("Reinitializing taskbar bounds...");
|
||||
taskbar.InitializeBounds();
|
||||
logger.Info("Desktop successfully restored.");
|
||||
}
|
||||
|
||||
private void ProcessMonitor_ExplorerStarted()
|
||||
{
|
||||
logger.Info("Trying to shut down explorer...");
|
||||
processMonitor.CloseExplorerShell();
|
||||
logger.Info("Reinitializing working area...");
|
||||
workingArea.InitializeFor(taskbar);
|
||||
displayMonitor.InitializePrimaryDisplay(taskbar.GetAbsoluteHeight());
|
||||
logger.Info("Reinitializing taskbar bounds...");
|
||||
taskbar.InitializeBounds();
|
||||
logger.Info("Desktop successfully restored.");
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
<Compile Include="Behaviour\Operations\ProcessMonitorOperation.cs" />
|
||||
<Compile Include="Behaviour\Operations\TaskbarOperation.cs" />
|
||||
<Compile Include="Behaviour\Operations\WindowMonitorOperation.cs" />
|
||||
<Compile Include="Behaviour\Operations\WorkingAreaOperation.cs" />
|
||||
<Compile Include="Behaviour\Operations\DisplayMonitorOperation.cs" />
|
||||
<Compile Include="Behaviour\ShutdownController.cs" />
|
||||
<Compile Include="Behaviour\StartupController.cs" />
|
||||
<Compile Include="Logging\DefaultLogFormatter.cs" />
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
using SafeExamBrowser.Contracts.WindowsApi;
|
||||
|
||||
namespace SafeExamBrowser.Configuration
|
||||
namespace SafeExamBrowser.Monitoring.Display
|
||||
{
|
||||
internal class Bounds : IBounds
|
||||
{
|
139
SafeExamBrowser.Monitoring/Display/DisplayMonitor.cs
Normal file
139
SafeExamBrowser.Monitoring/Display/DisplayMonitor.cs
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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.Windows.Forms;
|
||||
using Microsoft.Win32;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.Monitoring;
|
||||
using SafeExamBrowser.Contracts.WindowsApi;
|
||||
|
||||
namespace SafeExamBrowser.Monitoring.Display
|
||||
{
|
||||
public class DisplayMonitor : IDisplayMonitor
|
||||
{
|
||||
private IBounds originalWorkingArea;
|
||||
private ILogger logger;
|
||||
private INativeMethods nativeMethods;
|
||||
private string wallpaper;
|
||||
|
||||
public event DisplayChangedEventHandler DisplayChanged;
|
||||
|
||||
public DisplayMonitor(ILogger logger, INativeMethods nativeMethods)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.nativeMethods = nativeMethods;
|
||||
}
|
||||
|
||||
public void InitializePrimaryDisplay(int taskbarHeight)
|
||||
{
|
||||
InitializeWorkingArea(taskbarHeight);
|
||||
InitializeWallpaper();
|
||||
PreventSleepMode();
|
||||
}
|
||||
|
||||
public void ResetPrimaryDisplay()
|
||||
{
|
||||
ResetWorkingArea();
|
||||
ResetWallpaper();
|
||||
}
|
||||
|
||||
public void StartMonitoringDisplayChanges()
|
||||
{
|
||||
SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
|
||||
logger.Info("Started monitoring display changes.");
|
||||
}
|
||||
|
||||
public void StopMonitoringDisplayChanges()
|
||||
{
|
||||
SystemEvents.DisplaySettingsChanged -= SystemEvents_DisplaySettingsChanged;
|
||||
logger.Info("Stopped monitoring display changes.");
|
||||
}
|
||||
|
||||
private void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
|
||||
{
|
||||
logger.Info("Display change detected!");
|
||||
DisplayChanged?.Invoke();
|
||||
}
|
||||
|
||||
private void InitializeWorkingArea(int taskbarHeight)
|
||||
{
|
||||
var identifier = GetIdentifierForPrimaryDisplay();
|
||||
|
||||
originalWorkingArea = nativeMethods.GetWorkingArea();
|
||||
LogWorkingArea($"Saved original working area for {identifier}", originalWorkingArea);
|
||||
|
||||
var area = new Bounds
|
||||
{
|
||||
Left = 0,
|
||||
Top = 0,
|
||||
Right = Screen.PrimaryScreen.Bounds.Width,
|
||||
Bottom = Screen.PrimaryScreen.Bounds.Height - taskbarHeight
|
||||
};
|
||||
|
||||
LogWorkingArea($"Trying to set new working area for {identifier}", area);
|
||||
nativeMethods.SetWorkingArea(area);
|
||||
LogWorkingArea($"Working area of {identifier} is now set to", nativeMethods.GetWorkingArea());
|
||||
}
|
||||
|
||||
private void InitializeWallpaper()
|
||||
{
|
||||
var path = nativeMethods.GetWallpaperPath();
|
||||
|
||||
if (!String.IsNullOrEmpty(path))
|
||||
{
|
||||
wallpaper = path;
|
||||
logger.Info($"Saved wallpaper image: {wallpaper}.");
|
||||
nativeMethods.RemoveWallpaper();
|
||||
logger.Info("Removed current wallpaper.");
|
||||
}
|
||||
}
|
||||
|
||||
private void PreventSleepMode()
|
||||
{
|
||||
nativeMethods.DisableSleep();
|
||||
logger.Info("Disabled sleep mode and display timeout.");
|
||||
}
|
||||
|
||||
private void ResetWorkingArea()
|
||||
{
|
||||
var identifier = GetIdentifierForPrimaryDisplay();
|
||||
|
||||
if (originalWorkingArea != null)
|
||||
{
|
||||
nativeMethods.SetWorkingArea(originalWorkingArea);
|
||||
LogWorkingArea($"Restored original working area for {identifier}", originalWorkingArea);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.Warn($"Could not restore original working area for {identifier}!");
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetWallpaper()
|
||||
{
|
||||
if (!String.IsNullOrEmpty(wallpaper))
|
||||
{
|
||||
nativeMethods.SetWallpaper(wallpaper);
|
||||
logger.Info($"Restored wallpaper image: {wallpaper}.");
|
||||
}
|
||||
}
|
||||
|
||||
private string GetIdentifierForPrimaryDisplay()
|
||||
{
|
||||
var display = Screen.PrimaryScreen.DeviceName?.Replace(@"\\.\", string.Empty);
|
||||
|
||||
return $"{display} ({Screen.PrimaryScreen.Bounds.Width}x{Screen.PrimaryScreen.Bounds.Height})";
|
||||
}
|
||||
|
||||
private void LogWorkingArea(string message, IBounds area)
|
||||
{
|
||||
logger.Info($"{message}: Left = {area.Left}, Top = {area.Top}, Right = {area.Right}, Bottom = {area.Bottom}.");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -50,7 +50,9 @@
|
|||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
|
@ -60,10 +62,13 @@
|
|||
<Reference Include="WindowsBase" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Display\Bounds.cs" />
|
||||
<Compile Include="Display\DisplayMonitor.cs" />
|
||||
<Compile Include="Keyboard\KeyboardInterceptor.cs" />
|
||||
<Compile Include="Mouse\MouseInterceptor.cs" />
|
||||
<Compile Include="Processes\ProcessMonitor.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Windows\Window.cs" />
|
||||
<Compile Include="Windows\WindowMonitor.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
18
SafeExamBrowser.Monitoring/Windows/Window.cs
Normal file
18
SafeExamBrowser.Monitoring/Windows/Window.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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;
|
||||
|
||||
namespace SafeExamBrowser.Monitoring.Windows
|
||||
{
|
||||
internal struct Window
|
||||
{
|
||||
internal IntPtr Handle { get; set; }
|
||||
internal string Title { get; set; }
|
||||
}
|
||||
}
|
|
@ -117,11 +117,5 @@ namespace SafeExamBrowser.Monitoring.Windows
|
|||
{
|
||||
WindowChanged?.Invoke(window);
|
||||
}
|
||||
|
||||
private struct Window
|
||||
{
|
||||
internal IntPtr Handle { get; set; }
|
||||
internal string Title { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,14 +10,19 @@ using System.Windows;
|
|||
using System.Windows.Input;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using SafeExamBrowser.Contracts.Logging;
|
||||
using SafeExamBrowser.Contracts.UserInterface;
|
||||
|
||||
namespace SafeExamBrowser.UserInterface
|
||||
{
|
||||
public partial class Taskbar : Window, ITaskbar
|
||||
{
|
||||
public Taskbar()
|
||||
private ILogger logger;
|
||||
|
||||
public Taskbar(ILogger logger)
|
||||
{
|
||||
this.logger = logger;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
Loaded += (o, args) => InitializeBounds();
|
||||
|
@ -41,28 +46,13 @@ namespace SafeExamBrowser.UserInterface
|
|||
|
||||
public int GetAbsoluteHeight()
|
||||
{
|
||||
// WPF works with device-independent pixels. The following code is required
|
||||
// to get the real height of the taskbar (in absolute, device-specific pixels).
|
||||
// Source: https://stackoverflow.com/questions/3286175/how-do-i-convert-a-wpf-size-to-physical-pixels
|
||||
|
||||
return Dispatcher.Invoke(() =>
|
||||
{
|
||||
Matrix transformToDevice;
|
||||
var source = PresentationSource.FromVisual(this);
|
||||
var height = (int) TransformToPhysical(Width, Height).Y;
|
||||
|
||||
if (source != null)
|
||||
{
|
||||
transformToDevice = source.CompositionTarget.TransformToDevice;
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var newSource = new HwndSource(new HwndSourceParameters()))
|
||||
{
|
||||
transformToDevice = newSource.CompositionTarget.TransformToDevice;
|
||||
}
|
||||
}
|
||||
logger.Info($"Calculated absolute taskbar height is {height}px.");
|
||||
|
||||
return (int)transformToDevice.Transform((Vector)new Size(Width, Height)).Y;
|
||||
return height;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -73,6 +63,11 @@ namespace SafeExamBrowser.UserInterface
|
|||
Width = SystemParameters.WorkArea.Right;
|
||||
Left = SystemParameters.WorkArea.Right - Width;
|
||||
Top = SystemParameters.WorkArea.Bottom;
|
||||
|
||||
var position = TransformToPhysical(Left, Top);
|
||||
var size = TransformToPhysical(Width, Height);
|
||||
|
||||
logger.Info($"Set taskbar bounds to {Width}x{Height} at ({Left}/{Top}), in physical pixels: {size.X}x{size.Y} at ({position.X}/{position.Y}).");
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -106,5 +101,29 @@ namespace SafeExamBrowser.UserInterface
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Vector TransformToPhysical(double x, double y)
|
||||
{
|
||||
// WPF works with device-independent pixels. The following code is required
|
||||
// to transform those values to their absolute, device-specific pixel value.
|
||||
// Source: https://stackoverflow.com/questions/3286175/how-do-i-convert-a-wpf-size-to-physical-pixels
|
||||
|
||||
Matrix transformToDevice;
|
||||
var source = PresentationSource.FromVisual(this);
|
||||
|
||||
if (source != null)
|
||||
{
|
||||
transformToDevice = source.CompositionTarget.TransformToDevice;
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var newSource = new HwndSource(new HwndSourceParameters()))
|
||||
{
|
||||
transformToDevice = newSource.CompositionTarget.TransformToDevice;
|
||||
}
|
||||
}
|
||||
|
||||
return transformToDevice.Transform(new Vector(x, y));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,12 +14,11 @@ namespace SafeExamBrowser.WindowsApi.Constants
|
|||
internal enum SPI : uint
|
||||
{
|
||||
/// <summary>
|
||||
/// Sets the size of the work area. The work area is the portion of the screen not obscured by the system taskbar
|
||||
/// or by application desktop toolbars. The pvParam parameter is a pointer to a RECT structure that specifies the
|
||||
/// new work area rectangle, expressed in virtual screen coordinates. In a system with multiple display monitors,
|
||||
/// the function sets the work area of the monitor that contains the specified rectangle.
|
||||
/// Retrieves the full path of the bitmap file for the desktop wallpaper. The pvParam parameter must point to a buffer
|
||||
/// that receives a null-terminated path string. Set the uiParam parameter to the size, in characters, of the pvParam buffer.
|
||||
/// The returned string will not exceed MAX_PATH characters. If there is no desktop wallpaper, the returned string is empty.
|
||||
/// </summary>
|
||||
SETWORKAREA = 0x002F,
|
||||
GETDESKWALLPAPER = 0x73,
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the size of the work area on the primary display monitor. The work area is the portion of the screen
|
||||
|
@ -27,6 +26,21 @@ namespace SafeExamBrowser.WindowsApi.Constants
|
|||
/// RECT structure that receives the coordinates of the work area, expressed in virtual screen coordinates. To get
|
||||
/// the work area of a monitor other than the primary display monitor, call the GetMonitorInfo function.
|
||||
/// </summary>
|
||||
GETWORKAREA = 0x0030,
|
||||
GETWORKAREA = 0x30,
|
||||
|
||||
/// <summary>
|
||||
/// Sets the desktop wallpaper. The value of the pvParam parameter determines the new wallpaper. To specify a wallpaper bitmap,
|
||||
/// set pvParam to point to a null-terminated string containing the name of a bitmap file. Setting pvParam to "" removes the
|
||||
/// wallpaper. Setting pvParam to SETWALLPAPER_DEFAULT or null reverts to the default wallpaper.
|
||||
/// </summary>
|
||||
SETDESKWALLPAPER = 0x14,
|
||||
|
||||
/// <summary>
|
||||
/// Sets the size of the work area. The work area is the portion of the screen not obscured by the system taskbar
|
||||
/// or by application desktop toolbars. The pvParam parameter is a pointer to a RECT structure that specifies the
|
||||
/// new work area rectangle, expressed in virtual screen coordinates. In a system with multiple display monitors,
|
||||
/// the function sets the work area of the monitor that contains the specified rectangle.
|
||||
/// </summary>
|
||||
SETWORKAREA = 0x2F,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using SafeExamBrowser.WindowsApi.Types;
|
||||
|
||||
namespace SafeExamBrowser.WindowsApi
|
||||
{
|
||||
|
@ -16,7 +17,10 @@ namespace SafeExamBrowser.WindowsApi
|
|||
/// </summary>
|
||||
internal class Kernel32
|
||||
{
|
||||
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern IntPtr GetModuleHandle(string lpModuleName);
|
||||
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
internal static extern IntPtr GetModuleHandle(string lpModuleName);
|
||||
|
||||
[DllImport("kernel32.dll", SetLastError = true)]
|
||||
internal static extern EXECUTION_STATE SetThreadExecutionState(EXECUTION_STATE esFlags);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,6 +94,11 @@ namespace SafeExamBrowser.WindowsApi
|
|||
EventDelegates.TryRemove(handle, out EventProc d);
|
||||
}
|
||||
|
||||
public void DisableSleep()
|
||||
{
|
||||
Kernel32.SetThreadExecutionState(EXECUTION_STATE.CONTINUOUS | EXECUTION_STATE.DISPLAY_REQUIRED | EXECUTION_STATE.SYSTEM_REQUIRED);
|
||||
}
|
||||
|
||||
public void EmptyClipboard()
|
||||
{
|
||||
var success = true;
|
||||
|
@ -149,6 +154,22 @@ namespace SafeExamBrowser.WindowsApi
|
|||
return processId;
|
||||
}
|
||||
|
||||
public string GetWallpaperPath()
|
||||
{
|
||||
const int MAX_PATH = 260;
|
||||
var buffer = new String('\0', MAX_PATH);
|
||||
var success = User32.SystemParametersInfo(SPI.GETDESKWALLPAPER, buffer.Length, buffer, 0);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
throw new Win32Exception(Marshal.GetLastWin32Error());
|
||||
}
|
||||
|
||||
var path = buffer.Substring(0, buffer.IndexOf('\0'));
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
public string GetWindowTitle(IntPtr window)
|
||||
{
|
||||
var length = User32.GetWindowTextLength(window);
|
||||
|
@ -256,6 +277,11 @@ namespace SafeExamBrowser.WindowsApi
|
|||
return handle;
|
||||
}
|
||||
|
||||
public void RemoveWallpaper()
|
||||
{
|
||||
SetWallpaper(string.Empty);
|
||||
}
|
||||
|
||||
public void RestoreWindow(IntPtr window)
|
||||
{
|
||||
User32.ShowWindow(window, (int)ShowWindowCommand.Restore);
|
||||
|
@ -266,6 +292,16 @@ namespace SafeExamBrowser.WindowsApi
|
|||
User32.SendMessage(window, Constant.WM_SYSCOMMAND, (IntPtr) SystemCommand.CLOSE, IntPtr.Zero);
|
||||
}
|
||||
|
||||
public void SetWallpaper(string filePath)
|
||||
{
|
||||
var success = User32.SystemParametersInfo(SPI.SETDESKWALLPAPER, 0, filePath, SPIF.UPDATEANDCHANGE);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
throw new Win32Exception(Marshal.GetLastWin32Error());
|
||||
}
|
||||
}
|
||||
|
||||
public void SetWorkingArea(IBounds bounds)
|
||||
{
|
||||
var workingArea = new RECT { Left = bounds.Left, Top = bounds.Top, Right = bounds.Right, Bottom = bounds.Bottom };
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
<Compile Include="Constants\HookType.cs" />
|
||||
<Compile Include="Monitoring\MouseHook.cs" />
|
||||
<Compile Include="Types\Bounds.cs" />
|
||||
<Compile Include="Types\EXECUTION_STATE.cs" />
|
||||
<Compile Include="Types\KBDLLHOOKSTRUCT.cs" />
|
||||
<Compile Include="Types\KBDLLHOOKSTRUCTFlags.cs" />
|
||||
<Compile Include="Constants\ShowWindowCommand.cs" />
|
||||
|
|
25
SafeExamBrowser.WindowsApi/Types/EXECUTION_STATE.cs
Normal file
25
SafeExamBrowser.WindowsApi/Types/EXECUTION_STATE.cs
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2017 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;
|
||||
|
||||
namespace SafeExamBrowser.WindowsApi.Types
|
||||
{
|
||||
/// <remarks>
|
||||
/// See http://www.pinvoke.net/default.aspx/kernel32/SetThreadExecutionState.html.
|
||||
/// See https://msdn.microsoft.com/en-us/library/aa373208(v=vs.85).aspx.
|
||||
/// </remarks>
|
||||
[Flags]
|
||||
public enum EXECUTION_STATE : uint
|
||||
{
|
||||
AWAYMODE_REQUIRED = 0x00000040,
|
||||
CONTINUOUS = 0x80000000,
|
||||
DISPLAY_REQUIRED = 0x00000002,
|
||||
SYSTEM_REQUIRED = 0x00000001
|
||||
}
|
||||
}
|
|
@ -11,9 +11,9 @@ using SafeExamBrowser.Contracts.WindowsApi;
|
|||
|
||||
namespace SafeExamBrowser.WindowsApi.Types
|
||||
{
|
||||
/// <summary>
|
||||
/// <remarks>
|
||||
/// See https://msdn.microsoft.com/en-us/library/windows/desktop/dd162897(v=vs.85).aspx.
|
||||
/// </summary>
|
||||
/// </remarks>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct RECT
|
||||
{
|
||||
|
|
|
@ -38,10 +38,10 @@ namespace SafeExamBrowser.WindowsApi
|
|||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool EnumWindows(EnumWindowsDelegate enumProc, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
internal static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
|
@ -79,6 +79,10 @@ namespace SafeExamBrowser.WindowsApi
|
|||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool SystemParametersInfo(SPI uiAction, uint uiParam, ref RECT pvParam, SPIF fWinIni);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
internal static extern bool SystemParametersInfo(SPI uiAction, int uiParam, string pvParam, SPIF fWinIni);
|
||||
|
||||
[DllImport("user32.dll", SetLastError = true)]
|
||||
internal static extern bool UnhookWinEvent(IntPtr hWinEventHook);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ 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;
|
||||
|
@ -34,6 +35,7 @@ namespace SafeExamBrowser
|
|||
{
|
||||
private IApplicationController browserController;
|
||||
private IApplicationInfo browserInfo;
|
||||
private IDisplayMonitor displayMonitor;
|
||||
private IKeyboardInterceptor keyboardInterceptor;
|
||||
private ILogger logger;
|
||||
private ILogContentFormatter logFormatter;
|
||||
|
@ -46,7 +48,6 @@ namespace SafeExamBrowser
|
|||
private ITextResource textResource;
|
||||
private IUserInterfaceFactory uiFactory;
|
||||
private IWindowMonitor windowMonitor;
|
||||
private IWorkingArea workingArea;
|
||||
|
||||
public IShutdownController ShutdownController { get; private set; }
|
||||
public IStartupController StartupController { get; private set; }
|
||||
|
@ -59,22 +60,22 @@ namespace SafeExamBrowser
|
|||
logger = new Logger();
|
||||
logFormatter = new DefaultLogFormatter();
|
||||
nativeMethods = new NativeMethods();
|
||||
settings = new SettingsImpl();
|
||||
Taskbar = new Taskbar();
|
||||
settings = new Settings();
|
||||
textResource = new XmlTextResource();
|
||||
uiFactory = new UserInterfaceFactory();
|
||||
|
||||
logger.Subscribe(new LogFileWriter(logFormatter, settings));
|
||||
|
||||
text = new Text(textResource);
|
||||
Taskbar = new Taskbar(new ModuleLogger(logger, typeof(Taskbar)));
|
||||
browserController = new BrowserApplicationController(settings, text, uiFactory);
|
||||
displayMonitor = new DisplayMonitor(new ModuleLogger(logger, typeof(DisplayMonitor)), nativeMethods);
|
||||
keyboardInterceptor = new KeyboardInterceptor(settings.Keyboard, new ModuleLogger(logger, typeof(KeyboardInterceptor)));
|
||||
mouseInterceptor = new MouseInterceptor(new ModuleLogger(logger, typeof(MouseInterceptor)), settings.Mouse);
|
||||
processMonitor = new ProcessMonitor(new ModuleLogger(logger, typeof(ProcessMonitor)), nativeMethods);
|
||||
windowMonitor = new WindowMonitor(new ModuleLogger(logger, typeof(WindowMonitor)), nativeMethods);
|
||||
workingArea = new WorkingArea(new ModuleLogger(logger, typeof(WorkingArea)), nativeMethods);
|
||||
|
||||
runtimeController = new RuntimeController(new ModuleLogger(logger, typeof(RuntimeController)), processMonitor, Taskbar, windowMonitor, workingArea);
|
||||
runtimeController = new RuntimeController(displayMonitor, new ModuleLogger(logger, typeof(RuntimeController)), processMonitor, Taskbar, windowMonitor);
|
||||
ShutdownController = new ShutdownController(logger, settings, text, uiFactory);
|
||||
StartupController = new StartupController(logger, settings, text, uiFactory);
|
||||
|
||||
|
@ -82,7 +83,7 @@ namespace SafeExamBrowser
|
|||
StartupOperations.Enqueue(new KeyboardInterceptorOperation(keyboardInterceptor, logger, nativeMethods));
|
||||
StartupOperations.Enqueue(new WindowMonitorOperation(logger, windowMonitor));
|
||||
StartupOperations.Enqueue(new ProcessMonitorOperation(logger, processMonitor));
|
||||
StartupOperations.Enqueue(new WorkingAreaOperation(logger, Taskbar, workingArea));
|
||||
StartupOperations.Enqueue(new DisplayMonitorOperation(displayMonitor, logger, Taskbar));
|
||||
StartupOperations.Enqueue(new TaskbarOperation(logger, logFormatter, settings, Taskbar, text, uiFactory));
|
||||
StartupOperations.Enqueue(new BrowserOperation(browserController, browserInfo, logger, Taskbar, uiFactory));
|
||||
StartupOperations.Enqueue(new RuntimeControllerOperation(runtimeController, logger));
|
||||
|
|
Loading…
Reference in a new issue