diff --git a/SafeExamBrowser.Browser/BrowserApplicationInstance.cs b/SafeExamBrowser.Browser/BrowserApplicationInstance.cs
index 279578c3..a694efd1 100644
--- a/SafeExamBrowser.Browser/BrowserApplicationInstance.cs
+++ b/SafeExamBrowser.Browser/BrowserApplicationInstance.cs
@@ -63,7 +63,7 @@ namespace SafeExamBrowser.Browser
var downloadLogger = logger.CloneFor($"{nameof(DownloadHandler)} {Id}");
var downloadHandler = new DownloadHandler(appConfig, settings, downloadLogger);
- downloadHandler.ConfigurationDownloadRequested += (fileName, args) => ConfigurationDownloadRequested?.Invoke(fileName, args);
+ downloadHandler.ConfigurationDownloadRequested += DownloadHandler_ConfigurationDownloadRequested;
control = new BrowserControl(appConfig, settings, controlLogger, text);
control.AddressChanged += Control_AddressChanged;
@@ -101,6 +101,13 @@ namespace SafeExamBrowser.Browser
NameChanged?.Invoke(title);
}
+ private void DownloadHandler_ConfigurationDownloadRequested(string fileName, DownloadEventArgs args)
+ {
+ args.BrowserWindow = window;
+
+ ConfigurationDownloadRequested?.Invoke(fileName, args);
+ }
+
private void Window_AddressChanged(string address)
{
logger.Debug($"The user requested to navigate to '{address}'.");
diff --git a/SafeExamBrowser.Browser/Handlers/DownloadHandler.cs b/SafeExamBrowser.Browser/Handlers/DownloadHandler.cs
index 38ee5709..cb1dbb3d 100644
--- a/SafeExamBrowser.Browser/Handlers/DownloadHandler.cs
+++ b/SafeExamBrowser.Browser/Handlers/DownloadHandler.cs
@@ -82,6 +82,7 @@ namespace SafeExamBrowser.Browser.Handlers
{
var args = new DownloadEventArgs();
+ logger.Debug($"Detected download request for configuration file '{downloadItem.Url}'.");
ConfigurationDownloadRequested?.Invoke(downloadItem.SuggestedFileName, args);
logger.Debug($"Download of configuration file '{downloadItem.Url}' was {(args.AllowDownload ? "granted" : "denied")}.");
diff --git a/SafeExamBrowser.Client.UnitTests/Operations/WindowMonitorOperationTests.cs b/SafeExamBrowser.Client.UnitTests/Operations/WindowMonitorOperationTests.cs
index b4e6c7d7..5ee2beff 100644
--- a/SafeExamBrowser.Client.UnitTests/Operations/WindowMonitorOperationTests.cs
+++ b/SafeExamBrowser.Client.UnitTests/Operations/WindowMonitorOperationTests.cs
@@ -35,7 +35,6 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
sut.Perform();
- windowMonitorMock.Verify(w => w.HideAllWindows(), Times.Never);
windowMonitorMock.Verify(w => w.StartMonitoringWindows(), Times.Once);
}
@@ -47,7 +46,6 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
sut.Revert();
windowMonitorMock.Verify(w => w.StopMonitoringWindows(), Times.Once);
- windowMonitorMock.Verify(w => w.RestoreHiddenWindows(), Times.Never);
}
[TestMethod]
@@ -57,7 +55,6 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
sut.Perform();
- windowMonitorMock.Verify(w => w.HideAllWindows(), Times.Never);
windowMonitorMock.Verify(w => w.StartMonitoringWindows(), Times.Once);
}
@@ -69,7 +66,6 @@ namespace SafeExamBrowser.Client.UnitTests.Operations
sut.Revert();
windowMonitorMock.Verify(w => w.StopMonitoringWindows(), Times.Once);
- windowMonitorMock.Verify(w => w.RestoreHiddenWindows(), Times.Never);
}
[TestMethod]
diff --git a/SafeExamBrowser.Client/ClientController.cs b/SafeExamBrowser.Client/ClientController.cs
index c288dd93..8564025f 100644
--- a/SafeExamBrowser.Client/ClientController.cs
+++ b/SafeExamBrowser.Client/ClientController.cs
@@ -206,9 +206,11 @@ namespace SafeExamBrowser.Client
{
if (Settings.ConfigurationMode == ConfigurationMode.ConfigureClient)
{
- logger.Info($"Detected download request for configuration file '{fileName}'.");
+ logger.Debug($"Received download request for configuration file '{fileName}'. Asking user to confirm the reconfiguration...");
- var result = messageBox.Show(TextKey.MessageBox_ReconfigurationQuestion, TextKey.MessageBox_ReconfigurationQuestionTitle, MessageBoxAction.YesNo, MessageBoxIcon.Question);
+ var message = TextKey.MessageBox_ReconfigurationQuestion;
+ var title = TextKey.MessageBox_ReconfigurationQuestionTitle;
+ var result = messageBox.Show(message, title, MessageBoxAction.YesNo, MessageBoxIcon.Question, args.BrowserWindow);
var reconfigure = result == MessageBoxResult.Yes;
logger.Info($"The user chose to {(reconfigure ? "start" : "abort")} the reconfiguration.");
@@ -223,7 +225,7 @@ namespace SafeExamBrowser.Client
else
{
logger.Info($"Denied download request for configuration file '{fileName}' due to '{Settings.ConfigurationMode}' mode.");
- messageBox.Show(TextKey.MessageBox_ReconfigurationDenied, TextKey.MessageBox_ReconfigurationDeniedTitle);
+ messageBox.Show(TextKey.MessageBox_ReconfigurationDenied, TextKey.MessageBox_ReconfigurationDeniedTitle, parent: args.BrowserWindow);
}
}
diff --git a/SafeExamBrowser.Contracts/Browser/DownloadEventArgs.cs b/SafeExamBrowser.Contracts/Browser/DownloadEventArgs.cs
index 09c45e18..20e85dea 100644
--- a/SafeExamBrowser.Contracts/Browser/DownloadEventArgs.cs
+++ b/SafeExamBrowser.Contracts/Browser/DownloadEventArgs.cs
@@ -6,10 +6,12 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
+using SafeExamBrowser.Contracts.UserInterface.Browser;
+
namespace SafeExamBrowser.Contracts.Browser
{
///
- /// The event arguments used for all download events fired by the .
+ /// The event arguments used for all download events.
///
public class DownloadEventArgs
{
@@ -18,6 +20,11 @@ namespace SafeExamBrowser.Contracts.Browser
///
public bool AllowDownload { get; set; }
+ ///
+ /// The browser window from which the download request originated.
+ ///
+ public IBrowserWindow BrowserWindow { get; set; }
+
///
/// Callback executed once a download has been finished.
///
diff --git a/SafeExamBrowser.Contracts/Monitoring/IWindowMonitor.cs b/SafeExamBrowser.Contracts/Monitoring/IWindowMonitor.cs
index 774dc178..70c2d57f 100644
--- a/SafeExamBrowser.Contracts/Monitoring/IWindowMonitor.cs
+++ b/SafeExamBrowser.Contracts/Monitoring/IWindowMonitor.cs
@@ -31,16 +31,6 @@ namespace SafeExamBrowser.Contracts.Monitoring
///
bool Hide(IntPtr window);
- ///
- /// Hides all currently opened windows.
- ///
- void HideAllWindows();
-
- ///
- /// Restores all windows which were hidden during the startup procedure.
- ///
- void RestoreHiddenWindows();
-
///
/// Starts monitoring application windows by subscribing to specific system events.
/// If a window is shown which is not supposed to do so, it will be automatically hidden.
diff --git a/SafeExamBrowser.Contracts/WindowsApi/IExplorerShell.cs b/SafeExamBrowser.Contracts/WindowsApi/IExplorerShell.cs
index e46d7b6a..d9f77aae 100644
--- a/SafeExamBrowser.Contracts/WindowsApi/IExplorerShell.cs
+++ b/SafeExamBrowser.Contracts/WindowsApi/IExplorerShell.cs
@@ -13,6 +13,16 @@ namespace SafeExamBrowser.Contracts.WindowsApi
///
public interface IExplorerShell
{
+ ///
+ /// Hides all currently opened windows. The explorer shell needs to be running in order to execute this operation!
+ ///
+ void HideAllWindows();
+
+ ///
+ /// Restores all previously hidden windows. The explorer shell needs to be running in order to execute this operation!
+ ///
+ void RestoreAllWindows();
+
///
/// Resumes the explorer shell process, if it was previously suspended.
///
diff --git a/SafeExamBrowser.Monitoring/SafeExamBrowser.Monitoring.csproj b/SafeExamBrowser.Monitoring/SafeExamBrowser.Monitoring.csproj
index a3adfb66..8cdf993b 100644
--- a/SafeExamBrowser.Monitoring/SafeExamBrowser.Monitoring.csproj
+++ b/SafeExamBrowser.Monitoring/SafeExamBrowser.Monitoring.csproj
@@ -61,7 +61,6 @@
-
diff --git a/SafeExamBrowser.Monitoring/Windows/WindowMonitor.cs b/SafeExamBrowser.Monitoring/Windows/WindowMonitor.cs
index cca5ebcc..afab82bc 100644
--- a/SafeExamBrowser.Monitoring/Windows/WindowMonitor.cs
+++ b/SafeExamBrowser.Monitoring/Windows/WindowMonitor.cs
@@ -7,7 +7,6 @@
*/
using System;
-using System.Collections.Generic;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Contracts.Monitoring;
using SafeExamBrowser.Contracts.Monitoring.Events;
@@ -21,7 +20,6 @@ namespace SafeExamBrowser.Monitoring.Windows
private Guid? captureHookId;
private Guid? foregroundHookId;
private ILogger logger;
- private IList minimizedWindows = new List();
private INativeMethods nativeMethods;
public event WindowChangedEventHandler WindowChanged;
@@ -57,40 +55,6 @@ namespace SafeExamBrowser.Monitoring.Windows
return success;
}
- public void HideAllWindows()
- {
- logger.Info("Searching for windows to be minimized...");
-
- foreach (var handle in nativeMethods.GetOpenWindows())
- {
- var window = new Window
- {
- Handle = handle,
- Title = nativeMethods.GetWindowTitle(handle)
- };
-
- minimizedWindows.Add(window);
- logger.Info($"Found window '{window.Title}' with handle = {window.Handle}.");
- }
-
- logger.Info("Minimizing all open windows...");
- nativeMethods.MinimizeAllOpenWindows();
- logger.Info("Open windows successfully minimized.");
- }
-
- public void RestoreHiddenWindows()
- {
- logger.Info("Restoring all minimized windows...");
-
- foreach (var window in minimizedWindows)
- {
- nativeMethods.RestoreWindow(window.Handle);
- logger.Info($"Restored window '{window.Title}' with handle = {window.Handle}.");
- }
-
- logger.Info("Minimized windows successfully restored.");
- }
-
public void StartMonitoringWindows()
{
captureHookId = nativeMethods.RegisterSystemCaptureStartEvent(OnWindowChanged);
diff --git a/SafeExamBrowser.Runtime.UnitTests/Operations/KioskModeOperationTests.cs b/SafeExamBrowser.Runtime.UnitTests/Operations/KioskModeOperationTests.cs
index 6e140fd5..0592e149 100644
--- a/SafeExamBrowser.Runtime.UnitTests/Operations/KioskModeOperationTests.cs
+++ b/SafeExamBrowser.Runtime.UnitTests/Operations/KioskModeOperationTests.cs
@@ -80,6 +80,8 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
newDesktop.Verify(d => d.Activate(), Times.Once);
processFactory.VerifySet(f => f.StartupDesktop = newDesktop.Object, Times.Once);
explorerShell.Verify(s => s.Suspend(), Times.Once);
+ explorerShell.Verify(s => s.Terminate(), Times.Never);
+ explorerShell.Verify(s => s.HideAllWindows(), Times.Never);
Assert.AreSame(sessionContext.NewDesktop, newDesktop.Object);
Assert.AreSame(sessionContext.OriginalDesktop, originalDesktop.Object);
@@ -93,10 +95,15 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
[TestMethod]
public void MustCorrectlyInitializeDisableExplorerShell()
{
+ var order = 0;
+
nextSettings.KioskMode = KioskMode.DisableExplorerShell;
+ explorerShell.Setup(s => s.HideAllWindows()).Callback(() => Assert.AreEqual(1, ++order));
+ explorerShell.Setup(s => s.Terminate()).Callback(() => Assert.AreEqual(2, ++order));
sut.Perform();
+ explorerShell.Verify(s => s.HideAllWindows(), Times.Once);
explorerShell.Verify(s => s.Terminate(), Times.Once);
}
@@ -128,6 +135,8 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
processFactory.VerifySet(f => f.StartupDesktop = originalDesktop.Object, Times.Once);
newDesktop.Verify(d => d.Close(), Times.Once);
explorerShell.Verify(s => s.Resume(), Times.Once);
+ explorerShell.Verify(s => s.Start(), Times.Never);
+ explorerShell.Verify(s => s.RestoreAllWindows(), Times.Never);
Assert.AreEqual(OperationResult.Success, performResult);
Assert.AreEqual(OperationResult.Success, revertResult);
@@ -140,13 +149,18 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
[TestMethod]
public void MustCorrectlyRevertDisableExplorerShell()
{
+ var order = 0;
+
currentSettings.KioskMode = KioskMode.DisableExplorerShell;
nextSettings.KioskMode = KioskMode.DisableExplorerShell;
+ explorerShell.Setup(s => s.Start()).Callback(() => Assert.AreEqual(1, ++order));
+ explorerShell.Setup(s => s.RestoreAllWindows()).Callback(() => Assert.AreEqual(2, ++order));
var performResult = sut.Perform();
var revertResult = sut.Revert();
explorerShell.Verify(s => s.Start(), Times.Once);
+ explorerShell.Verify(s => s.RestoreAllWindows(), Times.Once);
Assert.AreEqual(OperationResult.Success, performResult);
Assert.AreEqual(OperationResult.Success, revertResult);
@@ -171,6 +185,8 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
explorerShell.Verify(s => s.Start(), Times.Never);
explorerShell.Verify(s => s.Resume(), Times.Never);
explorerShell.Verify(s => s.Suspend(), Times.Once);
+ explorerShell.Verify(s => s.HideAllWindows(), Times.Never);
+ explorerShell.Verify(s => s.RestoreAllWindows(), Times.Never);
newDesktop.Verify(d => d.Activate(), Times.Once);
newDesktop.Verify(d => d.Close(), Times.Never);
originalDesktop.Verify(d => d.Activate(), Times.Never);
@@ -181,10 +197,12 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
Assert.AreEqual(OperationResult.Success, result);
- explorerShell.Verify(s => s.Resume(), Times.Never);
explorerShell.Verify(s => s.Terminate(), Times.Once);
- explorerShell.Verify(s => s.Suspend(), Times.Once);
explorerShell.Verify(s => s.Start(), Times.Never);
+ explorerShell.Verify(s => s.Resume(), Times.Never);
+ explorerShell.Verify(s => s.Suspend(), Times.Once);
+ explorerShell.Verify(s => s.HideAllWindows(), Times.Once);
+ explorerShell.Verify(s => s.RestoreAllWindows(), Times.Never);
newDesktop.Verify(d => d.Activate(), Times.Once);
newDesktop.Verify(d => d.Close(), Times.Never);
originalDesktop.Verify(d => d.Activate(), Times.Never);
@@ -196,10 +214,12 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
Assert.AreEqual(OperationResult.Success, result);
- explorerShell.Verify(s => s.Resume(), Times.Never);
explorerShell.Verify(s => s.Terminate(), Times.Once);
- explorerShell.Verify(s => s.Suspend(), Times.Exactly(2));
explorerShell.Verify(s => s.Start(), Times.Never);
+ explorerShell.Verify(s => s.Resume(), Times.Never);
+ explorerShell.Verify(s => s.Suspend(), Times.Exactly(2));
+ explorerShell.Verify(s => s.HideAllWindows(), Times.Once);
+ explorerShell.Verify(s => s.RestoreAllWindows(), Times.Never);
newDesktop.Verify(d => d.Activate(), Times.Exactly(2));
newDesktop.Verify(d => d.Close(), Times.Never);
originalDesktop.Verify(d => d.Activate(), Times.Never);
diff --git a/SafeExamBrowser.Runtime.UnitTests/Operations/KioskModeTerminationOperationTests.cs b/SafeExamBrowser.Runtime.UnitTests/Operations/KioskModeTerminationOperationTests.cs
index 9fb83993..56eab478 100644
--- a/SafeExamBrowser.Runtime.UnitTests/Operations/KioskModeTerminationOperationTests.cs
+++ b/SafeExamBrowser.Runtime.UnitTests/Operations/KioskModeTerminationOperationTests.cs
@@ -88,6 +88,8 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
explorerShell.Verify(s => s.Start(), Times.Once);
explorerShell.Verify(s => s.Suspend(), Times.Never);
explorerShell.Verify(s => s.Terminate(), Times.Never);
+ explorerShell.Verify(s => s.HideAllWindows(), Times.Never);
+ explorerShell.Verify(s => s.RestoreAllWindows(), Times.Once);
newDesktop.Verify(d => d.Activate(), Times.Never);
newDesktop.Verify(d => d.Close(), Times.Never);
originalDesktop.Verify(d => d.Activate(), Times.Never);
@@ -103,6 +105,8 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
explorerShell.Verify(s => s.Start(), Times.Once);
explorerShell.Verify(s => s.Suspend(), Times.Never);
explorerShell.Verify(s => s.Terminate(), Times.Never);
+ explorerShell.Verify(s => s.HideAllWindows(), Times.Never);
+ explorerShell.Verify(s => s.RestoreAllWindows(), Times.Once);
newDesktop.Verify(d => d.Activate(), Times.Never);
newDesktop.Verify(d => d.Close(), Times.Once);
originalDesktop.Verify(d => d.Activate(), Times.Once);
@@ -118,6 +122,8 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
explorerShell.Verify(s => s.Start(), Times.Exactly(2));
explorerShell.Verify(s => s.Suspend(), Times.Never);
explorerShell.Verify(s => s.Terminate(), Times.Never);
+ explorerShell.Verify(s => s.HideAllWindows(), Times.Never);
+ explorerShell.Verify(s => s.RestoreAllWindows(), Times.Exactly(2));
newDesktop.Verify(d => d.Activate(), Times.Never);
newDesktop.Verify(d => d.Close(), Times.Once);
originalDesktop.Verify(d => d.Activate(), Times.Once);
@@ -126,7 +132,45 @@ namespace SafeExamBrowser.Runtime.UnitTests.Operations
[TestMethod]
public void MustNotTerminateKioskModeIfSameInNextSesssion()
{
+ var newDesktop = new Mock();
+ var originalDesktop = new Mock();
+ var result = default(OperationResult);
+ sessionContext.NewDesktop = newDesktop.Object;
+ sessionContext.OriginalDesktop = originalDesktop.Object;
+ sessionContext.ActiveMode = KioskMode.DisableExplorerShell;
+ nextSettings.KioskMode = KioskMode.DisableExplorerShell;
+
+ result = sut.Repeat();
+
+ Assert.AreEqual(OperationResult.Success, result);
+
+ explorerShell.Verify(s => s.Resume(), Times.Never);
+ explorerShell.Verify(s => s.Start(), Times.Never);
+ explorerShell.Verify(s => s.Suspend(), Times.Never);
+ explorerShell.Verify(s => s.Terminate(), Times.Never);
+ explorerShell.Verify(s => s.HideAllWindows(), Times.Never);
+ explorerShell.Verify(s => s.RestoreAllWindows(), Times.Never);
+ newDesktop.Verify(d => d.Activate(), Times.Never);
+ newDesktop.Verify(d => d.Close(), Times.Never);
+ originalDesktop.Verify(d => d.Activate(), Times.Never);
+
+ sessionContext.ActiveMode = KioskMode.CreateNewDesktop;
+ nextSettings.KioskMode = KioskMode.CreateNewDesktop;
+
+ result = sut.Repeat();
+
+ Assert.AreEqual(OperationResult.Success, result);
+
+ explorerShell.Verify(s => s.Resume(), Times.Never);
+ explorerShell.Verify(s => s.Start(), Times.Never);
+ explorerShell.Verify(s => s.Suspend(), Times.Never);
+ explorerShell.Verify(s => s.Terminate(), Times.Never);
+ explorerShell.Verify(s => s.HideAllWindows(), Times.Never);
+ explorerShell.Verify(s => s.RestoreAllWindows(), Times.Never);
+ newDesktop.Verify(d => d.Activate(), Times.Never);
+ newDesktop.Verify(d => d.Close(), Times.Never);
+ originalDesktop.Verify(d => d.Activate(), Times.Never);
}
[TestMethod]
diff --git a/SafeExamBrowser.Runtime/Operations/KioskModeOperation.cs b/SafeExamBrowser.Runtime/Operations/KioskModeOperation.cs
index b80f3995..ff6c04a2 100644
--- a/SafeExamBrowser.Runtime/Operations/KioskModeOperation.cs
+++ b/SafeExamBrowser.Runtime/Operations/KioskModeOperation.cs
@@ -158,17 +158,16 @@ namespace SafeExamBrowser.Runtime.Operations
{
StatusChanged?.Invoke(TextKey.OperationStatus_WaitExplorerTermination);
- // TODO: Hiding all windows must be done here, as the explorer shell is needed to do so!
-
+ explorerShell.HideAllWindows();
explorerShell.Terminate();
}
private void RestartExplorerShell()
{
StatusChanged?.Invoke(TextKey.OperationStatus_WaitExplorerStartup);
- explorerShell.Start();
- // TODO: Restore all hidden windows!
+ explorerShell.Start();
+ explorerShell.RestoreAllWindows();
}
}
}
diff --git a/SafeExamBrowser.Runtime/RuntimeController.cs b/SafeExamBrowser.Runtime/RuntimeController.cs
index 0a441c72..5a362008 100644
--- a/SafeExamBrowser.Runtime/RuntimeController.cs
+++ b/SafeExamBrowser.Runtime/RuntimeController.cs
@@ -448,9 +448,6 @@ namespace SafeExamBrowser.Runtime
runtimeWindow?.UpdateStatus(status, true);
}
- ///
- /// TODO: Move to utility in core library and use in client controller!
- ///
private void MapProgress(IProgressIndicator progressIndicator, ProgressChangedEventArgs args)
{
if (args.CurrentValue.HasValue)
diff --git a/SafeExamBrowser.WindowsApi/ExplorerShell.cs b/SafeExamBrowser.WindowsApi/ExplorerShell.cs
index 9cad87ad..f7b7996a 100644
--- a/SafeExamBrowser.WindowsApi/ExplorerShell.cs
+++ b/SafeExamBrowser.WindowsApi/ExplorerShell.cs
@@ -14,6 +14,7 @@ using System.Linq;
using System.Threading;
using SafeExamBrowser.Contracts.Logging;
using SafeExamBrowser.Contracts.WindowsApi;
+using SafeExamBrowser.WindowsApi.Types;
namespace SafeExamBrowser.WindowsApi
{
@@ -21,15 +22,51 @@ namespace SafeExamBrowser.WindowsApi
{
private ILogger logger;
private INativeMethods nativeMethods;
+ private IList minimizedWindows = new List();
private IList suspendedThreads;
public ExplorerShell(ILogger logger, INativeMethods nativeMethods)
{
this.logger = logger;
this.nativeMethods = nativeMethods;
+ this.minimizedWindows = new List();
this.suspendedThreads = new List();
}
+ public void HideAllWindows()
+ {
+ logger.Info("Searching for windows to be minimized...");
+
+ foreach (var handle in nativeMethods.GetOpenWindows())
+ {
+ var window = new Window
+ {
+ Handle = handle,
+ Title = nativeMethods.GetWindowTitle(handle)
+ };
+
+ minimizedWindows.Add(window);
+ logger.Info($"Found window '{window.Title}' with handle = {window.Handle}.");
+ }
+
+ logger.Info("Minimizing all open windows...");
+ nativeMethods.MinimizeAllOpenWindows();
+ logger.Info("Open windows successfully minimized.");
+ }
+
+ public void RestoreAllWindows()
+ {
+ logger.Info("Restoring all minimized windows...");
+
+ foreach (var window in minimizedWindows)
+ {
+ nativeMethods.RestoreWindow(window.Handle);
+ logger.Info($"Restored window '{window.Title}' with handle = {window.Handle}.");
+ }
+
+ logger.Info("Minimized windows successfully restored.");
+ }
+
public void Resume()
{
const int MAX_ATTEMPTS = 3;
diff --git a/SafeExamBrowser.WindowsApi/SafeExamBrowser.WindowsApi.csproj b/SafeExamBrowser.WindowsApi/SafeExamBrowser.WindowsApi.csproj
index 8b927bfb..b9df673a 100644
--- a/SafeExamBrowser.WindowsApi/SafeExamBrowser.WindowsApi.csproj
+++ b/SafeExamBrowser.WindowsApi/SafeExamBrowser.WindowsApi.csproj
@@ -83,6 +83,7 @@
+
diff --git a/SafeExamBrowser.Monitoring/Windows/Window.cs b/SafeExamBrowser.WindowsApi/Types/Window.cs
similarity index 90%
rename from SafeExamBrowser.Monitoring/Windows/Window.cs
rename to SafeExamBrowser.WindowsApi/Types/Window.cs
index 1b881686..3c009be0 100644
--- a/SafeExamBrowser.Monitoring/Windows/Window.cs
+++ b/SafeExamBrowser.WindowsApi/Types/Window.cs
@@ -8,7 +8,7 @@
using System;
-namespace SafeExamBrowser.Monitoring.Windows
+namespace SafeExamBrowser.WindowsApi.Types
{
internal struct Window
{