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:
parent
4f257c60f0
commit
14abfccc2e
4 changed files with 52 additions and 15 deletions
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue