Improved window handling and replaced whitespaces in log file names with underscores.
This commit is contained in:
parent
25105d61b1
commit
8c32d3bc4a
11 changed files with 134 additions and 50 deletions
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
21
SafeExamBrowser.WindowsApi/Constants/SystemCommand.cs
Normal file
21
SafeExamBrowser.WindowsApi/Constants/SystemCommand.cs
Normal 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
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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" />
|
||||
|
|
Loading…
Reference in a new issue