From 6a77a41564b4bf9ded3c550fd36ba19177bb8037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damian=20B=C3=BCchel?= Date: Thu, 25 Jul 2024 12:22:49 +0200 Subject: [PATCH] SEBWIN-917: Consolidated system (events) monitoring in sentinel. --- .../ClientControllerTests.cs | 9 +- .../Operations/SystemMonitorOperationTests.cs | 53 ----------- .../SafeExamBrowser.Client.UnitTests.csproj | 1 - SafeExamBrowser.Client/ClientController.cs | 90 ++++++++++--------- SafeExamBrowser.Client/CompositionRoot.cs | 3 - .../Operations/SystemMonitorOperation.cs | 51 ----------- .../SafeExamBrowser.Client.csproj | 1 - ...afeExamBrowser.Monitoring.Contracts.csproj | 1 - .../System/ISystemMonitor.cs | 33 ------- .../System/ISystemSentinel.cs | 10 +++ .../SafeExamBrowser.Monitoring.csproj | 2 +- .../SystemEvents.cs} | 51 +++++------ .../System/SystemSentinel.cs | 16 +++- 13 files changed, 102 insertions(+), 219 deletions(-) delete mode 100644 SafeExamBrowser.Client.UnitTests/Operations/SystemMonitorOperationTests.cs delete mode 100644 SafeExamBrowser.Client/Operations/SystemMonitorOperation.cs delete mode 100644 SafeExamBrowser.Monitoring.Contracts/System/ISystemMonitor.cs rename SafeExamBrowser.Monitoring/System/{SystemMonitor.cs => Components/SystemEvents.cs} (50%) diff --git a/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs b/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs index f77b33d8..bb05d4c9 100644 --- a/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs +++ b/SafeExamBrowser.Client.UnitTests/ClientControllerTests.cs @@ -73,7 +73,6 @@ namespace SafeExamBrowser.Client.UnitTests private AppSettings settings; private Mock shutdown; private Mock splashScreen; - private Mock systemMonitor; private Mock taskbar; private Mock text; private Mock uiFactory; @@ -108,7 +107,6 @@ namespace SafeExamBrowser.Client.UnitTests settings = new AppSettings(); shutdown = new Mock(); splashScreen = new Mock(); - systemMonitor = new Mock(); taskbar = new Mock(); text = new Mock(); uiFactory = new Mock(); @@ -134,7 +132,6 @@ namespace SafeExamBrowser.Client.UnitTests runtimeProxy.Object, shutdown.Object, splashScreen.Object, - systemMonitor.Object, sentinel.Object, taskbar.Object, text.Object, @@ -1288,7 +1285,7 @@ namespace SafeExamBrowser.Client.UnitTests .Returns(lockScreen.Object); sut.TryStart(); - systemMonitor.Raise(m => m.SessionChanged += null); + sentinel.Raise(s => s.SessionChanged += null); coordinator.Verify(c => c.RequestSessionLock(), Times.Once); coordinator.Verify(c => c.ReleaseSessionLock(), Times.Once); @@ -1311,7 +1308,7 @@ namespace SafeExamBrowser.Client.UnitTests .Returns(lockScreen.Object); sut.TryStart(); - systemMonitor.Raise(m => m.SessionChanged += null); + sentinel.Raise(s => s.SessionChanged += null); coordinator.Verify(c => c.RequestSessionLock(), Times.Once); coordinator.Verify(c => c.ReleaseSessionLock(), Times.Once); @@ -1333,7 +1330,7 @@ namespace SafeExamBrowser.Client.UnitTests .Returns(lockScreen.Object); sut.TryStart(); - systemMonitor.Raise(m => m.SessionChanged += null); + sentinel.Raise(s => s.SessionChanged += null); lockScreen.Verify(l => l.Show(), Times.Never); } diff --git a/SafeExamBrowser.Client.UnitTests/Operations/SystemMonitorOperationTests.cs b/SafeExamBrowser.Client.UnitTests/Operations/SystemMonitorOperationTests.cs deleted file mode 100644 index 4e6089dc..00000000 --- a/SafeExamBrowser.Client.UnitTests/Operations/SystemMonitorOperationTests.cs +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2024 ETH Zürich, IT Services - * - * 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 Microsoft.VisualStudio.TestTools.UnitTesting; -using Moq; -using SafeExamBrowser.Client.Operations; -using SafeExamBrowser.Logging.Contracts; -using SafeExamBrowser.Monitoring.Contracts.System; - -namespace SafeExamBrowser.Client.UnitTests.Operations -{ - [TestClass] - public class SystemMonitorOperationTests - { - private ClientContext context; - private Mock systemMonitor; - private Mock logger; - private SystemMonitorOperation sut; - - [TestInitialize] - public void Initialize() - { - context = new ClientContext(); - systemMonitor = new Mock(); - logger = new Mock(); - - sut = new SystemMonitorOperation(context, systemMonitor.Object, logger.Object); - } - - [TestMethod] - public void Perform_MustStartMonitor() - { - sut.Perform(); - - systemMonitor.Verify(s => s.Start(), Times.Once); - systemMonitor.VerifyNoOtherCalls(); - } - - [TestMethod] - public void Revert_MustStopMonitor() - { - sut.Revert(); - - systemMonitor.Verify(s => s.Stop(), Times.Once); - systemMonitor.VerifyNoOtherCalls(); - } - } -} diff --git a/SafeExamBrowser.Client.UnitTests/SafeExamBrowser.Client.UnitTests.csproj b/SafeExamBrowser.Client.UnitTests/SafeExamBrowser.Client.UnitTests.csproj index d84e9bb8..9eacc0bd 100644 --- a/SafeExamBrowser.Client.UnitTests/SafeExamBrowser.Client.UnitTests.csproj +++ b/SafeExamBrowser.Client.UnitTests/SafeExamBrowser.Client.UnitTests.csproj @@ -163,7 +163,6 @@ - diff --git a/SafeExamBrowser.Client/ClientController.cs b/SafeExamBrowser.Client/ClientController.cs index 0e7300ff..07389e28 100644 --- a/SafeExamBrowser.Client/ClientController.cs +++ b/SafeExamBrowser.Client/ClientController.cs @@ -66,7 +66,6 @@ namespace SafeExamBrowser.Client private readonly IRuntimeProxy runtime; private readonly Action shutdown; private readonly ISplashScreen splashScreen; - private readonly ISystemMonitor systemMonitor; private readonly ISystemSentinel sentinel; private readonly ITaskbar taskbar; private readonly IText text; @@ -97,7 +96,6 @@ namespace SafeExamBrowser.Client IRuntimeProxy runtime, Action shutdown, ISplashScreen splashScreen, - ISystemMonitor systemMonitor, ISystemSentinel sentinel, ITaskbar taskbar, IText text, @@ -118,7 +116,6 @@ namespace SafeExamBrowser.Client this.runtime = runtime; this.shutdown = shutdown; this.splashScreen = splashScreen; - this.systemMonitor = systemMonitor; this.sentinel = sentinel; this.taskbar = taskbar; this.text = text; @@ -144,6 +141,7 @@ namespace SafeExamBrowser.Client ShowShell(); AutoStartApplications(); ScheduleIntegrityVerification(); + StartMonitoring(); var communication = runtime.InformClientReady(); @@ -226,8 +224,8 @@ namespace SafeExamBrowser.Client runtime.ConnectionLost += Runtime_ConnectionLost; sentinel.CursorChanged += Sentinel_CursorChanged; sentinel.EaseOfAccessChanged += Sentinel_EaseOfAccessChanged; + sentinel.SessionChanged += Sentinel_SessionChanged; sentinel.StickyKeysChanged += Sentinel_StickyKeysChanged; - systemMonitor.SessionChanged += SystemMonitor_SessionChanged; taskbar.LoseFocusRequested += Taskbar_LoseFocusRequested; taskbar.QuitButtonClicked += Shell_QuitButtonClicked; @@ -253,8 +251,8 @@ namespace SafeExamBrowser.Client runtime.ConnectionLost -= Runtime_ConnectionLost; sentinel.CursorChanged -= Sentinel_CursorChanged; sentinel.EaseOfAccessChanged -= Sentinel_EaseOfAccessChanged; + sentinel.SessionChanged -= Sentinel_SessionChanged; sentinel.StickyKeysChanged -= Sentinel_StickyKeysChanged; - systemMonitor.SessionChanged -= SystemMonitor_SessionChanged; taskbar.LoseFocusRequested -= Taskbar_LoseFocusRequested; taskbar.QuitButtonClicked -= Shell_QuitButtonClicked; @@ -368,6 +366,11 @@ namespace SafeExamBrowser.Client timer.Elapsed += (o, args) => VerifyApplicationIntegrity(); timer.Interval = TEN_MINUTES + (new Random().NextDouble() * FIVE_MINUTES); timer.Start(); + } + + private void StartMonitoring() + { + sentinel.StartMonitoringSystemEvents(); if (!Settings.Security.AllowStickyKeys) { @@ -853,6 +856,47 @@ namespace SafeExamBrowser.Client } } + private void Sentinel_SessionChanged() + { + var allow = !Settings.Service.IgnoreService && (!Settings.Service.DisableUserLock || !Settings.Service.DisableUserSwitch); + var disable = Settings.Security.DisableSessionChangeLockScreen; + + if (allow || disable) + { + logger.Info($"Detected user session change, but {(allow ? "session locking and/or switching is allowed" : "lock screen is deactivated")}."); + } + else + { + var message = text.Get(TextKey.LockScreen_UserSessionMessage); + var title = text.Get(TextKey.LockScreen_Title); + var continueOption = new LockScreenOption { Text = text.Get(TextKey.LockScreen_UserSessionContinueOption) }; + var terminateOption = new LockScreenOption { Text = text.Get(TextKey.LockScreen_UserSessionTerminateOption) }; + + logger.Warn("User session changed! Attempting to show lock screen..."); + + if (coordinator.RequestSessionLock()) + { + var result = ShowLockScreen(message, title, new[] { continueOption, terminateOption }); + + if (result.OptionId == continueOption.Id) + { + logger.Info("The session will be allowed to resume as requested by the user..."); + } + else if (result.OptionId == terminateOption.Id) + { + logger.Info("Attempting to shutdown as requested by the user..."); + TryRequestShutdown(); + } + + coordinator.ReleaseSessionLock(); + } + else + { + logger.Warn("User session changed but lock screen is already active."); + } + } + } + private void Sentinel_StickyKeysChanged(SentinelEventArgs args) { if (coordinator.RequestSessionLock()) @@ -919,42 +963,6 @@ namespace SafeExamBrowser.Client ResumeActivators(); } - private void SystemMonitor_SessionChanged() - { - var allow = !Settings.Service.IgnoreService && (!Settings.Service.DisableUserLock || !Settings.Service.DisableUserSwitch); - var disable = Settings.Security.DisableSessionChangeLockScreen; - var message = text.Get(TextKey.LockScreen_UserSessionMessage); - var title = text.Get(TextKey.LockScreen_Title); - var continueOption = new LockScreenOption { Text = text.Get(TextKey.LockScreen_UserSessionContinueOption) }; - var terminateOption = new LockScreenOption { Text = text.Get(TextKey.LockScreen_UserSessionTerminateOption) }; - - if (allow || disable) - { - logger.Info($"Detected user session change, but {(allow ? "session locking and/or switching is allowed" : "lock screen is deactivated")}."); - } - else - { - logger.Warn("Detected user session change!"); - - if (coordinator.RequestSessionLock()) - { - var result = ShowLockScreen(message, title, new[] { continueOption, terminateOption }); - - if (result.OptionId == terminateOption.Id) - { - logger.Info("Attempting to shutdown as requested by the user..."); - TryRequestShutdown(); - } - - coordinator.ReleaseSessionLock(); - } - else - { - logger.Info("Lock screen is already active."); - } - } - } - private void Taskbar_LoseFocusRequested(bool forward) { Browser.Focus(forward); diff --git a/SafeExamBrowser.Client/CompositionRoot.cs b/SafeExamBrowser.Client/CompositionRoot.cs index 6bae424b..b9ad0d48 100644 --- a/SafeExamBrowser.Client/CompositionRoot.cs +++ b/SafeExamBrowser.Client/CompositionRoot.cs @@ -121,7 +121,6 @@ namespace SafeExamBrowser.Client var hashAlgorithm = new HashAlgorithm(); var sentinel = new SystemSentinel(ModuleLogger(nameof(SystemSentinel)), nativeMethods, registry); var splashScreen = uiFactory.CreateSplashScreen(); - var systemMonitor = new SystemMonitor(ModuleLogger(nameof(SystemMonitor))); var operations = new Queue(); @@ -137,7 +136,6 @@ namespace SafeExamBrowser.Client operations.Enqueue(new LazyInitializationOperation(BuildMouseInterceptorOperation)); operations.Enqueue(new ApplicationOperation(context, applicationFactory, applicationMonitor, logger, text)); operations.Enqueue(new DisplayMonitorOperation(context, displayMonitor, logger, taskbar)); - operations.Enqueue(new SystemMonitorOperation(context, systemMonitor, logger)); operations.Enqueue(new LazyInitializationOperation(BuildShellOperation)); operations.Enqueue(new LazyInitializationOperation(BuildBrowserOperation)); operations.Enqueue(new LazyInitializationOperation(BuildServerOperation)); @@ -162,7 +160,6 @@ namespace SafeExamBrowser.Client runtimeProxy, shutdown, splashScreen, - systemMonitor, sentinel, taskbar, text, diff --git a/SafeExamBrowser.Client/Operations/SystemMonitorOperation.cs b/SafeExamBrowser.Client/Operations/SystemMonitorOperation.cs deleted file mode 100644 index 1f1c3cc3..00000000 --- a/SafeExamBrowser.Client/Operations/SystemMonitorOperation.cs +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2024 ETH Zürich, IT Services - * - * 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.Core.Contracts.OperationModel; -using SafeExamBrowser.Core.Contracts.OperationModel.Events; -using SafeExamBrowser.I18n.Contracts; -using SafeExamBrowser.Logging.Contracts; -using SafeExamBrowser.Monitoring.Contracts.System; - -namespace SafeExamBrowser.Client.Operations -{ - internal class SystemMonitorOperation : ClientOperation - { - private readonly ILogger logger; - private readonly ISystemMonitor systemMonitor; - - public override event ActionRequiredEventHandler ActionRequired { add { } remove { } } - public override event StatusChangedEventHandler StatusChanged; - - public SystemMonitorOperation(ClientContext context, ISystemMonitor systemMonitor, ILogger logger) : base(context) - { - this.logger = logger; - this.systemMonitor = systemMonitor; - } - - public override OperationResult Perform() - { - logger.Info("Initializing system events..."); - StatusChanged?.Invoke(TextKey.OperationStatus_InitializeSystemEvents); - - systemMonitor.Start(); - - return OperationResult.Success; - } - - public override OperationResult Revert() - { - logger.Info("Finalizing system events..."); - StatusChanged?.Invoke(TextKey.OperationStatus_FinalizeSystemEvents); - - systemMonitor.Stop(); - - return OperationResult.Success; - } - } -} diff --git a/SafeExamBrowser.Client/SafeExamBrowser.Client.csproj b/SafeExamBrowser.Client/SafeExamBrowser.Client.csproj index 47c83612..f6026561 100644 --- a/SafeExamBrowser.Client/SafeExamBrowser.Client.csproj +++ b/SafeExamBrowser.Client/SafeExamBrowser.Client.csproj @@ -97,7 +97,6 @@ - Code diff --git a/SafeExamBrowser.Monitoring.Contracts/SafeExamBrowser.Monitoring.Contracts.csproj b/SafeExamBrowser.Monitoring.Contracts/SafeExamBrowser.Monitoring.Contracts.csproj index 6b6e264e..7987f8f0 100644 --- a/SafeExamBrowser.Monitoring.Contracts/SafeExamBrowser.Monitoring.Contracts.csproj +++ b/SafeExamBrowser.Monitoring.Contracts/SafeExamBrowser.Monitoring.Contracts.csproj @@ -73,7 +73,6 @@ - diff --git a/SafeExamBrowser.Monitoring.Contracts/System/ISystemMonitor.cs b/SafeExamBrowser.Monitoring.Contracts/System/ISystemMonitor.cs deleted file mode 100644 index a03514af..00000000 --- a/SafeExamBrowser.Monitoring.Contracts/System/ISystemMonitor.cs +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2024 ETH Zürich, IT Services - * - * 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.Monitoring.Contracts.System.Events; - -namespace SafeExamBrowser.Monitoring.Contracts.System -{ - /// - /// Monitors the operating system, e.g. for user account related events. - /// - public interface ISystemMonitor - { - /// - /// Event fired when the active user session has changed. - /// - event SessionChangedEventHandler SessionChanged; - - /// - /// Starts the monitoring. - /// - void Start(); - - /// - /// Stops the monitoring. - /// - void Stop(); - } -} diff --git a/SafeExamBrowser.Monitoring.Contracts/System/ISystemSentinel.cs b/SafeExamBrowser.Monitoring.Contracts/System/ISystemSentinel.cs index 33fe02fa..4a4036fc 100644 --- a/SafeExamBrowser.Monitoring.Contracts/System/ISystemSentinel.cs +++ b/SafeExamBrowser.Monitoring.Contracts/System/ISystemSentinel.cs @@ -25,6 +25,11 @@ namespace SafeExamBrowser.Monitoring.Contracts.System /// event SentinelEventHandler EaseOfAccessChanged; + /// + /// Event fired when the active user session has changed. + /// + event SessionChangedEventHandler SessionChanged; + /// /// Event fired when the sticky keys state has changed. /// @@ -60,6 +65,11 @@ namespace SafeExamBrowser.Monitoring.Contracts.System /// void StartMonitoringStickyKeys(); + /// + /// Starts monitoring the system events. + /// + void StartMonitoringSystemEvents(); + /// /// Stops all monitoring operations. /// diff --git a/SafeExamBrowser.Monitoring/SafeExamBrowser.Monitoring.csproj b/SafeExamBrowser.Monitoring/SafeExamBrowser.Monitoring.csproj index 39f8618b..39913247 100644 --- a/SafeExamBrowser.Monitoring/SafeExamBrowser.Monitoring.csproj +++ b/SafeExamBrowser.Monitoring/SafeExamBrowser.Monitoring.csproj @@ -70,7 +70,7 @@ - + diff --git a/SafeExamBrowser.Monitoring/System/SystemMonitor.cs b/SafeExamBrowser.Monitoring/System/Components/SystemEvents.cs similarity index 50% rename from SafeExamBrowser.Monitoring/System/SystemMonitor.cs rename to SafeExamBrowser.Monitoring/System/Components/SystemEvents.cs index 432d2917..f0baffd4 100644 --- a/SafeExamBrowser.Monitoring/System/SystemMonitor.cs +++ b/SafeExamBrowser.Monitoring/System/Components/SystemEvents.cs @@ -10,46 +10,47 @@ using System; using System.Threading.Tasks; using Microsoft.Win32; using SafeExamBrowser.Logging.Contracts; -using SafeExamBrowser.Monitoring.Contracts.System; using SafeExamBrowser.Monitoring.Contracts.System.Events; -namespace SafeExamBrowser.Monitoring.System +namespace SafeExamBrowser.Monitoring.System.Components { - public class SystemMonitor : ISystemMonitor + internal class SystemEvents { private readonly ILogger logger; - public event SessionChangedEventHandler SessionChanged; + internal event SessionChangedEventHandler SessionChanged; - public SystemMonitor(ILogger logger) + internal SystemEvents(ILogger logger) { this.logger = logger; } - public void Start() + internal void StartMonitoring() { - SystemEvents.EventsThreadShutdown += SystemEvents_EventsThreadShutdown; - SystemEvents.InstalledFontsChanged += SystemEvents_InstalledFontsChanged; - SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; - SystemEvents.SessionEnded += SystemEvents_SessionEnded; - SystemEvents.SessionEnding += SystemEvents_SessionEnding; - SystemEvents.SessionSwitch += SystemEvents_SessionChanged; - SystemEvents.TimeChanged += SystemEvents_TimeChanged; - SystemEvents.UserPreferenceChanged += SystemEvents_UserPreferenceChanged; - logger.Info("Started monitoring the operating system."); + Microsoft.Win32.SystemEvents.EventsThreadShutdown += SystemEvents_EventsThreadShutdown; + Microsoft.Win32.SystemEvents.InstalledFontsChanged += SystemEvents_InstalledFontsChanged; + Microsoft.Win32.SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged; + Microsoft.Win32.SystemEvents.SessionEnded += SystemEvents_SessionEnded; + Microsoft.Win32.SystemEvents.SessionEnding += SystemEvents_SessionEnding; + Microsoft.Win32.SystemEvents.SessionSwitch += SystemEvents_SessionChanged; + Microsoft.Win32.SystemEvents.TimeChanged += SystemEvents_TimeChanged; + Microsoft.Win32.SystemEvents.UserPreferenceChanged += SystemEvents_UserPreferenceChanged; + + logger.Info("Started monitoring system events."); } - public void Stop() + internal void StopMonitoring() { - SystemEvents.EventsThreadShutdown -= SystemEvents_EventsThreadShutdown; - SystemEvents.InstalledFontsChanged -= SystemEvents_InstalledFontsChanged; - SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged; - SystemEvents.SessionEnded -= SystemEvents_SessionEnded; - SystemEvents.SessionEnding -= SystemEvents_SessionEnding; - SystemEvents.SessionSwitch -= SystemEvents_SessionChanged; - SystemEvents.TimeChanged -= SystemEvents_TimeChanged; - SystemEvents.UserPreferenceChanged -= SystemEvents_UserPreferenceChanged; - logger.Info("Stopped monitoring the operating system."); + Microsoft.Win32.SystemEvents.EventsThreadShutdown -= SystemEvents_EventsThreadShutdown; + Microsoft.Win32.SystemEvents.InstalledFontsChanged -= SystemEvents_InstalledFontsChanged; + Microsoft.Win32.SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged; + Microsoft.Win32.SystemEvents.SessionEnded -= SystemEvents_SessionEnded; + Microsoft.Win32.SystemEvents.SessionEnding -= SystemEvents_SessionEnding; + Microsoft.Win32.SystemEvents.SessionSwitch -= SystemEvents_SessionChanged; + Microsoft.Win32.SystemEvents.TimeChanged -= SystemEvents_TimeChanged; + Microsoft.Win32.SystemEvents.UserPreferenceChanged -= SystemEvents_UserPreferenceChanged; + + logger.Info("Stopped monitoring system events."); } private void SystemEvents_EventsThreadShutdown(object sender, EventArgs e) diff --git a/SafeExamBrowser.Monitoring/System/SystemSentinel.cs b/SafeExamBrowser.Monitoring/System/SystemSentinel.cs index 60e09750..6a823bd7 100644 --- a/SafeExamBrowser.Monitoring/System/SystemSentinel.cs +++ b/SafeExamBrowser.Monitoring/System/SystemSentinel.cs @@ -20,16 +20,19 @@ namespace SafeExamBrowser.Monitoring.System private readonly Cursors cursors; private readonly EaseOfAccess easeOfAccess; private readonly StickyKeys stickyKeys; + private readonly SystemEvents systemEvents; public event SentinelEventHandler CursorChanged; public event SentinelEventHandler EaseOfAccessChanged; public event SentinelEventHandler StickyKeysChanged; + public event SessionChangedEventHandler SessionChanged; public SystemSentinel(ILogger logger, INativeMethods nativeMethods, IRegistry registry) { - this.cursors = new Cursors(logger, registry); - this.easeOfAccess = new EaseOfAccess(logger, registry); - this.stickyKeys = new StickyKeys(logger, nativeMethods); + cursors = new Cursors(logger, registry); + easeOfAccess = new EaseOfAccess(logger, registry); + stickyKeys = new StickyKeys(logger, nativeMethods); + systemEvents = new SystemEvents(logger); } public bool DisableStickyKeys() @@ -65,11 +68,18 @@ namespace SafeExamBrowser.Monitoring.System stickyKeys.StartMonitoring(); } + public void StartMonitoringSystemEvents() + { + systemEvents.SessionChanged += () => SessionChanged?.Invoke(); + systemEvents.StartMonitoring(); + } + public void StopMonitoring() { cursors.StopMonitoring(); easeOfAccess.StopMonitoring(); stickyKeys.StopMonitoring(); + systemEvents.StopMonitoring(); } public bool VerifyCursors()