SEBWIN-226: Changed termination mechanism of explorer shell to accommodate bug (?) in Windows and fixed setting of working area parameters.

This commit is contained in:
dbuechel 2019-03-19 12:26:03 +01:00
parent 4f257c60f0
commit 14abfccc2e
4 changed files with 52 additions and 15 deletions

View file

@ -16,7 +16,7 @@ namespace SafeExamBrowser.Configuration.ConfigurationData
private void MapKioskMode(IDictionary<string, object> rawData, Settings settings) private void MapKioskMode(IDictionary<string, object> rawData, Settings settings)
{ {
var hasCreateNewDesktop = rawData.TryGetValue(Keys.Security.KioskModeCreateNewDesktop, out var createNewDesktop); var hasCreateNewDesktop = rawData.TryGetValue(Keys.Security.KioskModeCreateNewDesktop, out var createNewDesktop);
var hasDisableExplorerShell = rawData.TryGetValue(Keys.Security.KioskModeCreateNewDesktop, out var disableExplorerShell); var hasDisableExplorerShell = rawData.TryGetValue(Keys.Security.KioskModeDisableExplorerShell, out var disableExplorerShell);
if (hasDisableExplorerShell && disableExplorerShell as bool? == true) if (hasDisableExplorerShell && disableExplorerShell as bool? == true)
{ {

View file

@ -62,6 +62,8 @@ namespace SafeExamBrowser.Runtime.Operations
logger.Info($"Initializing kiosk mode '{Context.Next.Settings.KioskMode}'..."); logger.Info($"Initializing kiosk mode '{Context.Next.Settings.KioskMode}'...");
StatusChanged?.Invoke(TextKey.OperationStatus_InitializeKioskMode); StatusChanged?.Invoke(TextKey.OperationStatus_InitializeKioskMode);
ActiveMode = Context.Next.Settings.KioskMode;
switch (Context.Next.Settings.KioskMode) switch (Context.Next.Settings.KioskMode)
{ {
case KioskMode.CreateNewDesktop: case KioskMode.CreateNewDesktop:
@ -72,8 +74,6 @@ namespace SafeExamBrowser.Runtime.Operations
break; break;
} }
ActiveMode = Context.Next.Settings.KioskMode;
return OperationResult.Success; return OperationResult.Success;
} }

View file

@ -99,12 +99,14 @@ namespace SafeExamBrowser.WindowsApi
var process = new System.Diagnostics.Process(); var process = new System.Diagnostics.Process();
var explorerPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "explorer.exe"); var explorerPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "explorer.exe");
logger.Info("Restarting explorer shell..."); logger.Debug("Starting explorer shell process...");
process.StartInfo.CreateNoWindow = true; process.StartInfo.CreateNoWindow = true;
process.StartInfo.FileName = explorerPath; process.StartInfo.FileName = explorerPath;
process.Start(); process.Start();
logger.Debug("Waiting for explorer shell to initialize...");
while (nativeMethods.GetShellWindowHandle() == IntPtr.Zero) while (nativeMethods.GetShellWindowHandle() == IntPtr.Zero)
{ {
Thread.Sleep(20); Thread.Sleep(20);
@ -119,13 +121,13 @@ namespace SafeExamBrowser.WindowsApi
{ {
var processId = nativeMethods.GetShellProcessId(); var processId = nativeMethods.GetShellProcessId();
var explorerProcesses = System.Diagnostics.Process.GetProcessesByName("explorer"); var explorerProcesses = System.Diagnostics.Process.GetProcessesByName("explorer");
var shellProcess = explorerProcesses.FirstOrDefault(p => p.Id == processId); var process = explorerProcesses.FirstOrDefault(p => p.Id == processId);
if (shellProcess != null) if (process != null)
{ {
logger.Debug($"Found explorer shell processes with PID = {processId} and {shellProcess.Threads.Count} threads."); logger.Debug($"Found explorer shell processes with PID = {processId} and {process.Threads.Count} threads.");
foreach (ProcessThread thread in shellProcess.Threads) foreach (ProcessThread thread in process.Threads)
{ {
var success = nativeMethods.SuspendThread(thread.Id); var success = nativeMethods.SuspendThread(thread.Id);
@ -140,6 +142,7 @@ namespace SafeExamBrowser.WindowsApi
} }
logger.Info($"Successfully suspended explorer shell process with PID = {processId}."); logger.Info($"Successfully suspended explorer shell process with PID = {processId}.");
process.Close();
} }
else else
{ {
@ -149,28 +152,62 @@ namespace SafeExamBrowser.WindowsApi
public void Terminate() public void Terminate()
{ {
const int THREE_SECONDS = 3000;
var processId = nativeMethods.GetShellProcessId(); var processId = nativeMethods.GetShellProcessId();
var explorerProcesses = System.Diagnostics.Process.GetProcessesByName("explorer"); var explorerProcesses = System.Diagnostics.Process.GetProcessesByName("explorer");
var shellProcess = explorerProcesses.FirstOrDefault(p => p.Id == processId); var process = explorerProcesses.FirstOrDefault(p => p.Id == processId);
if (shellProcess != null) if (process != null)
{ {
logger.Debug($"Found explorer shell processes with PID = {processId}. Sending close message..."); logger.Debug($"Found explorer shell processes with PID = {processId}. Sending close message...");
nativeMethods.PostCloseMessageToShell(); nativeMethods.PostCloseMessageToShell();
logger.Debug("Waiting for explorer shell to terminate...");
while (!shellProcess.HasExited) while (nativeMethods.GetShellWindowHandle() != IntPtr.Zero)
{ {
shellProcess.Refresh();
Thread.Sleep(20); Thread.Sleep(20);
} }
logger.Info($"Successfully terminated explorer shell process with PID = {processId}."); process.WaitForExit(THREE_SECONDS);
process.Refresh();
if (!process.HasExited)
{
KillExplorerShell(process.Id);
}
process.Refresh();
if (process.HasExited)
{
logger.Info($"Successfully terminated explorer shell process with PID = {processId}.");
}
else
{
logger.Error($"Failed to completely terminate explorer shell process with PID = {processId}.");
}
process.Close();
} }
else else
{ {
logger.Info("The explorer shell seems to already be terminated."); logger.Info("The explorer shell seems to already be terminated.");
} }
} }
private void KillExplorerShell(int processId)
{
var process = new System.Diagnostics.Process();
var taskkillPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "taskkill.exe");
logger.Warn("Failed to gracefully terminate, attempting forceful termination...");
process.StartInfo.Arguments = $"/F /PID {processId}";
process.StartInfo.CreateNoWindow = true;
process.StartInfo.FileName = taskkillPath;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.Start();
process.WaitForExit();
}
} }
} }

View file

@ -370,7 +370,7 @@ namespace SafeExamBrowser.WindowsApi
public void SetWorkingArea(IBounds bounds) public void SetWorkingArea(IBounds bounds)
{ {
var workingArea = new RECT { Left = bounds.Left, Top = bounds.Top, Right = bounds.Right, Bottom = bounds.Bottom }; var workingArea = new RECT { Left = bounds.Left, Top = bounds.Top, Right = bounds.Right, Bottom = bounds.Bottom };
var success = User32.SystemParametersInfo(SPI.SETWORKAREA, 0, ref workingArea, SPIF.NONE); var success = User32.SystemParametersInfo(SPI.SETWORKAREA, 0, ref workingArea, SPIF.UPDATEINIFILE);
if (!success) if (!success)
{ {