Improved window handling and replaced whitespaces in log file names with underscores.

This commit is contained in:
dbuechel 2017-07-27 13:57:12 +02:00
parent 25105d61b1
commit 8c32d3bc4a
11 changed files with 134 additions and 50 deletions

View file

@ -16,16 +16,16 @@ namespace SafeExamBrowser.Configuration
public class Settings : ISettings
{
private const string AppDataFolder = "SafeExamBrowser";
private static readonly string LogFileDate = DateTime.Now.ToString("yyyy-MM-dd HH\\hmm\\mss\\s");
private static readonly string LogFileDate = DateTime.Now.ToString("yyyy-MM-dd\\_HH\\hmm\\mss\\s");
public string ApplicationLogFile
{
get { return Path.Combine(LogFolderPath, $"{LogFileDate} Application.txt"); }
get { return Path.Combine(LogFolderPath, $"{LogFileDate}_Application.txt"); }
}
public string BrowserLogFile
{
get { return Path.Combine(LogFolderPath, $"{LogFileDate} Browser.txt"); }
get { return Path.Combine(LogFolderPath, $"{LogFileDate}_Browser.txt"); }
}
public string BrowserCachePath

View file

@ -20,17 +20,16 @@ namespace SafeExamBrowser.Contracts.Monitoring
/// </summary>
event ExplorerStartedHandler ExplorerStarted;
/// <summary>
/// Performs a check whether the process associated to the given window is allowed.
/// </summary>
bool BelongsToAllowedProcess(IntPtr window);
/// <summary>
/// Terminates the Windows explorer shell, i.e. the taskbar.
/// </summary>
void CloseExplorerShell();
/// <summary>
/// Performs a check whether the process associated to the given window is allowed,
/// i.e. whether the specified window should be hidden.
/// </summary>
void OnWindowChanged(IntPtr window, out bool hide);
/// <summary>
/// Starts a new instance of the Windows explorer shell.
/// </summary>

View file

@ -10,7 +10,7 @@ using System;
namespace SafeExamBrowser.Contracts.Monitoring
{
public delegate void WindowChangedHandler(IntPtr window, out bool hide);
public delegate void WindowChangedHandler(IntPtr window);
public interface IWindowMonitor
{
@ -19,6 +19,16 @@ namespace SafeExamBrowser.Contracts.Monitoring
/// </summary>
event WindowChangedHandler WindowChanged;
/// <summary>
/// Forcefully closes the specified window.
/// </summary>
void Close(IntPtr window);
/// <summary>
/// Hides the specified window. Returns <c>true</c> if the window was successfully hidden, otherwise <c>false</c>.
/// </summary>
bool Hide(IntPtr window);
/// <summary>
/// Hides all currently opened windows.
/// </summary>

View file

@ -54,9 +54,9 @@ namespace SafeExamBrowser.Contracts.WindowsApi
RECT GetWorkingArea();
/// <summary>
/// Hides the given window.
/// Hides the given window. Returns <c>true</c> if successful, otherwise <c>false</c>.
/// </summary>
void HideWindow(IntPtr window);
bool HideWindow(IntPtr window);
/// <summary>
/// Minimizes all open windows.
@ -88,6 +88,11 @@ namespace SafeExamBrowser.Contracts.WindowsApi
/// </summary>
void RestoreWindow(IntPtr window);
/// <summary>
/// Sends a close message to the given window.
/// </summary>
void SendCloseMessageTo(IntPtr window);
/// <summary>
/// Sets the working area of the primary screen according to the given dimensions.
/// </summary>

View file

@ -6,6 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
using System;
using SafeExamBrowser.Contracts.Behaviour;
using SafeExamBrowser.Contracts.Configuration;
using SafeExamBrowser.Contracts.Logging;
@ -39,13 +40,13 @@ namespace SafeExamBrowser.Core.Behaviour
public void Start()
{
processMonitor.ExplorerStarted += ProcessMonitor_ExplorerStarted;
windowMonitor.WindowChanged += processMonitor.OnWindowChanged;
windowMonitor.WindowChanged += WindowMonitor_WindowChanged;
}
public void Stop()
{
processMonitor.ExplorerStarted -= ProcessMonitor_ExplorerStarted;
windowMonitor.WindowChanged -= processMonitor.OnWindowChanged;
windowMonitor.WindowChanged -= WindowMonitor_WindowChanged;
}
private void ProcessMonitor_ExplorerStarted()
@ -56,7 +57,22 @@ namespace SafeExamBrowser.Core.Behaviour
workingArea.InitializeFor(taskbar);
logger.Info("Reinitializing taskbar bounds...");
taskbar.InitializeBounds();
logger.Info("Desktop successfully restored!");
logger.Info("Desktop successfully restored.");
}
private void WindowMonitor_WindowChanged(IntPtr window)
{
var allowed = processMonitor.BelongsToAllowedProcess(window);
if (!allowed)
{
var success = windowMonitor.Hide(window);
if (!success)
{
windowMonitor.Close(window);
}
}
}
}
}

View file

@ -32,6 +32,26 @@ namespace SafeExamBrowser.Monitoring.Processes
this.nativeMethods = nativeMethods;
}
public bool BelongsToAllowedProcess(IntPtr window)
{
var processId = nativeMethods.GetProcessIdFor(window);
var process = Process.GetProcessById(Convert.ToInt32(processId));
if (process != null)
{
var allowed = process.ProcessName == "SafeExamBrowser";
if (!allowed)
{
logger.Warn($"Window with handle = {window} belongs to not allowed process '{process.ProcessName}'!");
}
return allowed;
}
return true;
}
public void CloseExplorerShell()
{
var processId = nativeMethods.GetShellProcessId();
@ -58,21 +78,6 @@ namespace SafeExamBrowser.Monitoring.Processes
}
}
public void OnWindowChanged(IntPtr window, out bool hide)
{
var processId = nativeMethods.GetProcessIdFor(window);
var process = Process.GetProcessById(Convert.ToInt32(processId));
if (process != null)
{
hide = process.ProcessName != "SafeExamBrowser";
}
else
{
hide = true;
}
}
public void StartExplorerShell()
{
var process = new Process();

View file

@ -30,6 +30,31 @@ namespace SafeExamBrowser.Monitoring.Windows
this.nativeMethods = nativeMethods;
}
public void Close(IntPtr window)
{
var title = nativeMethods.GetWindowTitle(window);
nativeMethods.SendCloseMessageTo(window);
logger.Info($"Sent close message to window '{title}' with handle = {window}.");
}
public bool Hide(IntPtr window)
{
var title = nativeMethods.GetWindowTitle(window);
var success = nativeMethods.HideWindow(window);
if (success)
{
logger.Info($"Hid window '{title}' with handle = {window}.");
}
else
{
logger.Warn($"Failed to hide window '{title}' with handle = {window}!");
}
return success;
}
public void HideAllWindows()
{
logger.Info("Saving windows to be minimized...");
@ -90,18 +115,7 @@ namespace SafeExamBrowser.Monitoring.Windows
private void OnWindowChanged(IntPtr window)
{
if (WindowChanged != null)
{
WindowChanged.Invoke(window, out bool hide);
if (hide)
{
var title = nativeMethods.GetWindowTitle(window);
nativeMethods.HideWindow(window);
logger.Info($"Hid window '{title}' with handle = {window}.");
}
}
WindowChanged?.Invoke(window);
}
private struct Window

View file

@ -48,5 +48,13 @@ namespace SafeExamBrowser.WindowsApi.Constants
/// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms647591(v=vs.85).aspx.
/// </summary>
internal const int WM_COMMAND = 0x111;
/// <summary>
/// A window receives this message when the user chooses a command from the Window menu (formerly known as the system or control
/// menu) or when the user chooses the maximize button, minimize button, restore button, or close button.
///
/// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms646360(v=vs.85).aspx.
/// </summary>
internal const int WM_SYSCOMMAND = 0x112;
}
}

View file

@ -0,0 +1,21 @@
/*
* 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.WindowsApi.Constants
{
/// <summary>
/// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms646360(v=vs.85).aspx.
/// </summary>
internal enum SystemCommand
{
/// <summary>
/// Closes the window.
/// </summary>
CLOSE = 0xF060
}
}

View file

@ -1,10 +1,10 @@
/*
* 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/.
*/
* 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.Collections.Concurrent;
@ -92,9 +92,9 @@ namespace SafeExamBrowser.WindowsApi
return workingArea;
}
public void HideWindow(IntPtr window)
public bool HideWindow(IntPtr window)
{
User32.ShowWindow(window, (int)ShowWindowCommand.Hide);
return User32.ShowWindow(window, (int) ShowWindowCommand.Hide);
}
public void MinimizeAllOpenWindows()
@ -157,6 +157,11 @@ namespace SafeExamBrowser.WindowsApi
User32.ShowWindow(window, (int)ShowWindowCommand.Restore);
}
public void SendCloseMessageTo(IntPtr window)
{
User32.SendMessage(window, Constant.WM_SYSCOMMAND, (IntPtr) SystemCommand.CLOSE, IntPtr.Zero);
}
public void SetWorkingArea(RECT bounds)
{
var success = User32.SystemParametersInfo(SPI.SETWORKAREA, 0, ref bounds, SPIF.UPDATEANDCHANGE);

View file

@ -60,6 +60,7 @@
<ItemGroup>
<Compile Include="Constants\Constant.cs" />
<Compile Include="Constants\ShowWindowCommand.cs" />
<Compile Include="Constants\SystemCommand.cs" />
<Compile Include="NativeMethods.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Constants\SPI.cs" />