SEBWIN-219: Implemented draft of communication operation and runtime communication host.
This commit is contained in:
		
							parent
							
								
									c10e141e7f
								
							
						
					
					
						commit
						8cd0659a22
					
				
					 32 changed files with 626 additions and 170 deletions
				
			
		| 
						 | 
					@ -58,7 +58,7 @@ namespace SafeExamBrowser.Client
 | 
				
			||||||
			browserInfo = new BrowserApplicationInfo();
 | 
								browserInfo = new BrowserApplicationInfo();
 | 
				
			||||||
			logger = new Logger();
 | 
								logger = new Logger();
 | 
				
			||||||
			nativeMethods = new NativeMethods();
 | 
								nativeMethods = new NativeMethods();
 | 
				
			||||||
			settings = new SettingsRepository().LoadDefaults();
 | 
								settings = new ConfigurationRepository().LoadDefaultSettings();
 | 
				
			||||||
			systemInfo = new SystemInfo();
 | 
								systemInfo = new SystemInfo();
 | 
				
			||||||
			uiFactory = new UserInterfaceFactory();
 | 
								uiFactory = new UserInterfaceFactory();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										87
									
								
								SafeExamBrowser.Configuration/ConfigurationRepository.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								SafeExamBrowser.Configuration/ConfigurationRepository.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,87 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2018 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.IO;
 | 
				
			||||||
 | 
					using System.Reflection;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Configuration;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Configuration.Settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace SafeExamBrowser.Configuration
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						public class ConfigurationRepository : IConfigurationRepository
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							private RuntimeInfo runtimeInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public ISettings CurrentSettings { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public IRuntimeInfo RuntimeInfo
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								get
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									if (runtimeInfo == null)
 | 
				
			||||||
 | 
									{
 | 
				
			||||||
 | 
										InitializeRuntimeInfo();
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									return runtimeInfo;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public ISettings LoadSettings(Uri path)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								// TODO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return LoadDefaultSettings();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public ISettings LoadDefaultSettings()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								var settings = new Settings.Settings();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// TODO
 | 
				
			||||||
 | 
								settings.ServicePolicy = ServicePolicy.Optional;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								CurrentSettings = settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								return settings;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void InitializeRuntimeInfo()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								var appDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), nameof(SafeExamBrowser));
 | 
				
			||||||
 | 
								var baseAddress = "net.pipe://localhost/safeexambrowser";
 | 
				
			||||||
 | 
								var clientId = Guid.NewGuid();
 | 
				
			||||||
 | 
								var executable = Assembly.GetEntryAssembly();
 | 
				
			||||||
 | 
								var runtimeId = Guid.NewGuid();
 | 
				
			||||||
 | 
								var startTime = DateTime.Now;
 | 
				
			||||||
 | 
								var logFolder = Path.Combine(appDataFolder, "Logs");
 | 
				
			||||||
 | 
								var logFilePrefix = startTime.ToString("yyyy-MM-dd\\_HH\\hmm\\mss\\s");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								runtimeInfo = new RuntimeInfo
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									ApplicationStartTime = startTime,
 | 
				
			||||||
 | 
									AppDataFolder = appDataFolder,
 | 
				
			||||||
 | 
									BrowserCachePath = Path.Combine(appDataFolder, "Cache"),
 | 
				
			||||||
 | 
									BrowserLogFile = Path.Combine(logFolder, $"{logFilePrefix}_Browser.txt"),
 | 
				
			||||||
 | 
									ClientId = Guid.NewGuid(),
 | 
				
			||||||
 | 
									ClientAddress = $"{baseAddress}/client/{clientId}",
 | 
				
			||||||
 | 
									ClientLogFile = Path.Combine(logFolder, $"{logFilePrefix}_Client.txt"),
 | 
				
			||||||
 | 
									DefaultSettingsFileName = "SebClientSettings.seb",
 | 
				
			||||||
 | 
									ProgramCopyright = executable.GetCustomAttribute<AssemblyCopyrightAttribute>().Copyright,
 | 
				
			||||||
 | 
									ProgramDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), nameof(SafeExamBrowser)),
 | 
				
			||||||
 | 
									ProgramTitle = executable.GetCustomAttribute<AssemblyTitleAttribute>().Title,
 | 
				
			||||||
 | 
									ProgramVersion = executable.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion,
 | 
				
			||||||
 | 
									RuntimeId = Guid.NewGuid(),
 | 
				
			||||||
 | 
									RuntimeAddress = $"{baseAddress}/runtime/{runtimeId}",
 | 
				
			||||||
 | 
									RuntimeLogFile = Path.Combine(logFolder, $"{logFilePrefix}_Runtime.txt"),
 | 
				
			||||||
 | 
									ServiceAddress = $"{baseAddress}/service"
 | 
				
			||||||
 | 
								};
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -18,12 +18,17 @@ namespace SafeExamBrowser.Configuration
 | 
				
			||||||
		public DateTime ApplicationStartTime { get; set; }
 | 
							public DateTime ApplicationStartTime { get; set; }
 | 
				
			||||||
		public string BrowserCachePath { get; set; }
 | 
							public string BrowserCachePath { get; set; }
 | 
				
			||||||
		public string BrowserLogFile { get; set; }
 | 
							public string BrowserLogFile { get; set; }
 | 
				
			||||||
 | 
							public string ClientAddress { get; set; }
 | 
				
			||||||
 | 
							public Guid ClientId { get; set; }
 | 
				
			||||||
		public string ClientLogFile { get; set; }
 | 
							public string ClientLogFile { get; set; }
 | 
				
			||||||
		public string DefaultSettingsFileName { get; set; }
 | 
							public string DefaultSettingsFileName { get; set; }
 | 
				
			||||||
		public string ProgramCopyright { get; set; }
 | 
							public string ProgramCopyright { get; set; }
 | 
				
			||||||
		public string ProgramDataFolder { get; set; }
 | 
							public string ProgramDataFolder { get; set; }
 | 
				
			||||||
		public string ProgramTitle { get; set; }
 | 
							public string ProgramTitle { get; set; }
 | 
				
			||||||
		public string ProgramVersion { get; set; }
 | 
							public string ProgramVersion { get; set; }
 | 
				
			||||||
 | 
							public string RuntimeAddress { get; set; }
 | 
				
			||||||
 | 
							public Guid RuntimeId { get; set; }
 | 
				
			||||||
		public string RuntimeLogFile { get; set; }
 | 
							public string RuntimeLogFile { get; set; }
 | 
				
			||||||
 | 
							public string ServiceAddress { get; set; }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,7 +59,7 @@
 | 
				
			||||||
    <Compile Include="Settings\MouseSettings.cs" />
 | 
					    <Compile Include="Settings\MouseSettings.cs" />
 | 
				
			||||||
    <Compile Include="Settings\Settings.cs" />
 | 
					    <Compile Include="Settings\Settings.cs" />
 | 
				
			||||||
    <Compile Include="Properties\AssemblyInfo.cs" />
 | 
					    <Compile Include="Properties\AssemblyInfo.cs" />
 | 
				
			||||||
    <Compile Include="Settings\SettingsRepository.cs" />
 | 
					    <Compile Include="ConfigurationRepository.cs" />
 | 
				
			||||||
    <Compile Include="SystemInfo.cs" />
 | 
					    <Compile Include="SystemInfo.cs" />
 | 
				
			||||||
    <Compile Include="Settings\TaskbarSettings.cs" />
 | 
					    <Compile Include="Settings\TaskbarSettings.cs" />
 | 
				
			||||||
  </ItemGroup>
 | 
					  </ItemGroup>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,37 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 * Copyright (c) 2018 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 SafeExamBrowser.Contracts.Configuration.Settings;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace SafeExamBrowser.Configuration.Settings
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	public class SettingsRepository : ISettingsRepository
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		public ISettings Current { get; private set; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		public ISettings Load(Uri path)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			// TODO
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			return LoadDefaults();
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		public ISettings LoadDefaults()
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			var settings = new Settings();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			// TODO
 | 
					 | 
				
			||||||
			settings.ServicePolicy = ServicePolicy.Optional;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			Current = settings;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			return settings;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -6,6 +6,7 @@
 | 
				
			||||||
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
					 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace SafeExamBrowser.Contracts.Behaviour
 | 
					namespace SafeExamBrowser.Contracts.Behaviour
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	public interface IRuntimeController
 | 
						public interface IRuntimeController
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,28 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2018 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.Contracts.Communication
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						public interface ICommunicationHost
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// Indicates whether the host is running and ready for communication.
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							bool IsRunning { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// Starts the host and opens it for communication.
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							void Start();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// Closes and terminates the host.
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							void Stop();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										15
									
								
								SafeExamBrowser.Contracts/Communication/IRuntimeHost.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								SafeExamBrowser.Contracts/Communication/IRuntimeHost.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2018 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.Contracts.Communication
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						public interface IRuntimeHost : ICommunicationHost
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -7,26 +7,32 @@
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Configuration.Settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace SafeExamBrowser.Contracts.Configuration.Settings
 | 
					namespace SafeExamBrowser.Contracts.Configuration
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	public interface ISettingsRepository
 | 
						public interface IConfigurationRepository
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Retrieves the current settings, i.e. the last ones which were loaded. If no settings have been loaded yet, this property will
 | 
							/// Retrieves the current settings, i.e. the last ones which were loaded. If no settings have been loaded yet, this property will
 | 
				
			||||||
		/// be <c>null</c>.
 | 
							/// be <c>null</c>!
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		ISettings Current { get; }
 | 
							ISettings CurrentSettings { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// The runtime information for the currently running application instance.
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							IRuntimeInfo RuntimeInfo { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Attempts to load settings from the specified path.
 | 
							/// Attempts to load settings from the specified path.
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		/// <exception cref="System.ArgumentException">Thrown if the given path cannot be resolved to a settings file.</exception>
 | 
							/// <exception cref="ArgumentException">Thrown if the given path cannot be resolved to a settings file.</exception>
 | 
				
			||||||
		ISettings Load(Uri path);
 | 
							ISettings LoadSettings(Uri path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// Loads the default settings.
 | 
							/// Loads the default settings.
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		ISettings LoadDefaults();
 | 
							ISettings LoadDefaultSettings();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -32,6 +32,22 @@ namespace SafeExamBrowser.Contracts.Configuration
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		string BrowserLogFile { get; }
 | 
							string BrowserLogFile { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// The communication address of the client component.
 | 
				
			||||||
 | 
							/// 
 | 
				
			||||||
 | 
							/// TODO: Will need to be updated for each new client instance!
 | 
				
			||||||
 | 
							/// 
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							string ClientAddress { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// The unique identifier for the currently running client instance.
 | 
				
			||||||
 | 
							/// 
 | 
				
			||||||
 | 
							/// TODO: Will need to be updated for each new client instance!
 | 
				
			||||||
 | 
							/// 
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							Guid ClientId { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// The file path under which the log of the client component is to be stored.
 | 
							/// The file path under which the log of the client component is to be stored.
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
| 
						 | 
					@ -62,9 +78,24 @@ namespace SafeExamBrowser.Contracts.Configuration
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		string ProgramVersion { get; }
 | 
							string ProgramVersion { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// The communication address of the runtime component.
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							string RuntimeAddress { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// The unique identifier for the currently running runtime instance.
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							Guid RuntimeId { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/// <summary>
 | 
							/// <summary>
 | 
				
			||||||
		/// The file path under which the log of the runtime component is to be stored.
 | 
							/// The file path under which the log of the runtime component is to be stored.
 | 
				
			||||||
		/// </summary>
 | 
							/// </summary>
 | 
				
			||||||
		string RuntimeLogFile { get; }
 | 
							string RuntimeLogFile { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/// <summary>
 | 
				
			||||||
 | 
							/// The communication address of the service component.
 | 
				
			||||||
 | 
							/// </summary>
 | 
				
			||||||
 | 
							string ServiceAddress { get; }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,12 +35,15 @@ namespace SafeExamBrowser.Contracts.I18n
 | 
				
			||||||
		ProgressIndicator_InitializeTaskbar,
 | 
							ProgressIndicator_InitializeTaskbar,
 | 
				
			||||||
		ProgressIndicator_InitializeWindowMonitoring,
 | 
							ProgressIndicator_InitializeWindowMonitoring,
 | 
				
			||||||
		ProgressIndicator_InitializeWorkingArea,
 | 
							ProgressIndicator_InitializeWorkingArea,
 | 
				
			||||||
 | 
							ProgressIndicator_RestartCommunicationHost,
 | 
				
			||||||
		ProgressIndicator_RestoreWorkingArea,
 | 
							ProgressIndicator_RestoreWorkingArea,
 | 
				
			||||||
		ProgressIndicator_RevertKioskMode,
 | 
							ProgressIndicator_RevertKioskMode,
 | 
				
			||||||
		ProgressIndicator_ShutdownProcedure,
 | 
							ProgressIndicator_ShutdownProcedure,
 | 
				
			||||||
 | 
							ProgressIndicator_StartCommunicationHost,
 | 
				
			||||||
		ProgressIndicator_StartEventHandling,
 | 
							ProgressIndicator_StartEventHandling,
 | 
				
			||||||
		ProgressIndicator_StartKeyboardInterception,
 | 
							ProgressIndicator_StartKeyboardInterception,
 | 
				
			||||||
		ProgressIndicator_StartMouseInterception,
 | 
							ProgressIndicator_StartMouseInterception,
 | 
				
			||||||
 | 
							ProgressIndicator_StopCommunicationHost,
 | 
				
			||||||
		ProgressIndicator_StopEventHandling,
 | 
							ProgressIndicator_StopEventHandling,
 | 
				
			||||||
		ProgressIndicator_StopKeyboardInterception,
 | 
							ProgressIndicator_StopKeyboardInterception,
 | 
				
			||||||
		ProgressIndicator_StopMouseInterception,
 | 
							ProgressIndicator_StopMouseInterception,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,6 +58,8 @@
 | 
				
			||||||
    <Compile Include="Behaviour\Operations\IOperationSequence.cs" />
 | 
					    <Compile Include="Behaviour\Operations\IOperationSequence.cs" />
 | 
				
			||||||
    <Compile Include="Communication\ICommunication.cs" />
 | 
					    <Compile Include="Communication\ICommunication.cs" />
 | 
				
			||||||
    <Compile Include="Communication\IClientProxy.cs" />
 | 
					    <Compile Include="Communication\IClientProxy.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Communication\ICommunicationHost.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Communication\IRuntimeHost.cs" />
 | 
				
			||||||
    <Compile Include="Communication\IRuntimeProxy.cs" />
 | 
					    <Compile Include="Communication\IRuntimeProxy.cs" />
 | 
				
			||||||
    <Compile Include="Communication\IServiceProxy.cs" />
 | 
					    <Compile Include="Communication\IServiceProxy.cs" />
 | 
				
			||||||
    <Compile Include="Communication\Messages\IMessage.cs" />
 | 
					    <Compile Include="Communication\Messages\IMessage.cs" />
 | 
				
			||||||
| 
						 | 
					@ -78,7 +80,7 @@
 | 
				
			||||||
    <Compile Include="Configuration\Settings\IKeyboardSettings.cs" />
 | 
					    <Compile Include="Configuration\Settings\IKeyboardSettings.cs" />
 | 
				
			||||||
    <Compile Include="Configuration\Settings\IMouseSettings.cs" />
 | 
					    <Compile Include="Configuration\Settings\IMouseSettings.cs" />
 | 
				
			||||||
    <Compile Include="Configuration\Settings\ISettings.cs" />
 | 
					    <Compile Include="Configuration\Settings\ISettings.cs" />
 | 
				
			||||||
    <Compile Include="Configuration\Settings\ISettingsRepository.cs" />
 | 
					    <Compile Include="Configuration\IConfigurationRepository.cs" />
 | 
				
			||||||
    <Compile Include="Configuration\Settings\ITaskbarSettings.cs" />
 | 
					    <Compile Include="Configuration\Settings\ITaskbarSettings.cs" />
 | 
				
			||||||
    <Compile Include="Configuration\Settings\KioskMode.cs" />
 | 
					    <Compile Include="Configuration\Settings\KioskMode.cs" />
 | 
				
			||||||
    <Compile Include="Configuration\Settings\ServicePolicy.cs" />
 | 
					    <Compile Include="Configuration\Settings\ServicePolicy.cs" />
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,70 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2018 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 Microsoft.VisualStudio.TestTools.UnitTesting;
 | 
				
			||||||
 | 
					using Moq;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Communication;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Logging;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Core.Behaviour.Operations;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						[TestClass]
 | 
				
			||||||
 | 
						public class CommunicationOperationTests
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							private Mock<ICommunicationHost> hostMock;
 | 
				
			||||||
 | 
							private Mock<ILogger> loggerMock;
 | 
				
			||||||
 | 
							private CommunicationOperation sut;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[TestInitialize]
 | 
				
			||||||
 | 
							public void Initialize()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								hostMock = new Mock<ICommunicationHost>();
 | 
				
			||||||
 | 
								loggerMock = new Mock<ILogger>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								sut = new CommunicationOperation(hostMock.Object, loggerMock.Object);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[TestMethod]
 | 
				
			||||||
 | 
							public void MustRestartHostOnRepeat()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								var order = 0;
 | 
				
			||||||
 | 
								var stop = 0;
 | 
				
			||||||
 | 
								var start = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								hostMock.Setup(h => h.Stop()).Callback(() => stop = ++order);
 | 
				
			||||||
 | 
								hostMock.Setup(h => h.Start()).Callback(() => start = ++order);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								sut.Repeat();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								hostMock.Verify(h => h.Stop(), Times.Once);
 | 
				
			||||||
 | 
								hostMock.Verify(h => h.Start(), Times.Once);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								Assert.AreEqual(stop, 1);
 | 
				
			||||||
 | 
								Assert.AreEqual(start, 2);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[TestMethod]
 | 
				
			||||||
 | 
							public void MustStartHostOnPerform()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								sut.Perform();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								hostMock.Verify(h => h.Start(), Times.Once);
 | 
				
			||||||
 | 
								hostMock.Verify(h => h.Stop(), Times.Never);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[TestMethod]
 | 
				
			||||||
 | 
							public void MustStopHostOnRevert()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								sut.Revert();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								hostMock.Verify(h => h.Stop(), Times.Once);
 | 
				
			||||||
 | 
								hostMock.Verify(h => h.Start(), Times.Never);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -28,6 +28,29 @@ namespace SafeExamBrowser.Core.UnitTests.Behaviour.Operations
 | 
				
			||||||
			loggerMock = new Mock<ILogger>();
 | 
								loggerMock = new Mock<ILogger>();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							[TestMethod]
 | 
				
			||||||
 | 
							public void MustCreateCopyOfOperationQueue()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								var operationA = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operationB = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operationC = new Mock<IOperation>();
 | 
				
			||||||
 | 
								var operations = new Queue<IOperation>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								operations.Enqueue(operationA.Object);
 | 
				
			||||||
 | 
								operations.Enqueue(operationB.Object);
 | 
				
			||||||
 | 
								operations.Enqueue(operationC.Object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								var sut = new OperationSequence(loggerMock.Object, operations);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								operations.Clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								sut.TryPerform();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								operationA.Verify(o => o.Perform(), Times.Once);
 | 
				
			||||||
 | 
								operationB.Verify(o => o.Perform(), Times.Once);
 | 
				
			||||||
 | 
								operationC.Verify(o => o.Perform(), Times.Once);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		#region Perform Tests
 | 
							#region Perform Tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[TestMethod]
 | 
							[TestMethod]
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -78,6 +78,7 @@
 | 
				
			||||||
    <Reference Include="System.Xml" />
 | 
					    <Reference Include="System.Xml" />
 | 
				
			||||||
  </ItemGroup>
 | 
					  </ItemGroup>
 | 
				
			||||||
  <ItemGroup>
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <Compile Include="Behaviour\Operations\CommunicationOperationTests.cs" />
 | 
				
			||||||
    <Compile Include="Behaviour\Operations\I18nOperationTests.cs" />
 | 
					    <Compile Include="Behaviour\Operations\I18nOperationTests.cs" />
 | 
				
			||||||
    <Compile Include="Behaviour\Operations\OperationSequenceTests.cs" />
 | 
					    <Compile Include="Behaviour\Operations\OperationSequenceTests.cs" />
 | 
				
			||||||
    <Compile Include="I18n\TextTests.cs" />
 | 
					    <Compile Include="I18n\TextTests.cs" />
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,59 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2018 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 SafeExamBrowser.Contracts.Behaviour.Operations;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Communication;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.I18n;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Logging;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.UserInterface;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace SafeExamBrowser.Core.Behaviour.Operations
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						public class CommunicationOperation : IOperation
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							private ICommunicationHost host;
 | 
				
			||||||
 | 
							private ILogger logger;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public bool Abort { get; private set; }
 | 
				
			||||||
 | 
							public IProgressIndicator ProgressIndicator { private get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public CommunicationOperation(ICommunicationHost host, ILogger logger)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								this.host = host;
 | 
				
			||||||
 | 
								this.logger = logger;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public void Perform()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								logger.Info("Starting communication host...");
 | 
				
			||||||
 | 
								ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StartCommunicationHost);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								host.Start();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public void Repeat()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								if (!host.IsRunning)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									logger.Info("Restarting communication host...");
 | 
				
			||||||
 | 
									ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_RestartCommunicationHost);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									host.Stop();
 | 
				
			||||||
 | 
									host.Start();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public void Revert()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								logger.Info("Stopping communication host...");
 | 
				
			||||||
 | 
								ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StopCommunicationHost);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								host.Stop();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -40,7 +40,7 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (!success)
 | 
									if (!success)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					Revert();
 | 
										Revert(true);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			catch (Exception e)
 | 
								catch (Exception e)
 | 
				
			||||||
| 
						 | 
					@ -74,8 +74,8 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			try
 | 
								try
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				Initialize();
 | 
									Initialize(true);
 | 
				
			||||||
				success = Revert(false);
 | 
									success = Revert();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			catch (Exception e)
 | 
								catch (Exception e)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
| 
						 | 
					@ -154,7 +154,7 @@ namespace SafeExamBrowser.Core.Behaviour.Operations
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private bool Revert(bool regress = true)
 | 
							private bool Revert(bool regress = false)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			var success = true;
 | 
								var success = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										91
									
								
								SafeExamBrowser.Core/Communication/BaseHost.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								SafeExamBrowser.Core/Communication/BaseHost.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,91 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2018 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.ServiceModel;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Communication;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Communication.Messages;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Communication.Responses;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Logging;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace SafeExamBrowser.Core.Communication
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Single)]
 | 
				
			||||||
 | 
						public abstract class BaseHost : ICommunication, ICommunicationHost
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							private string address;
 | 
				
			||||||
 | 
							private ILogger logger;
 | 
				
			||||||
 | 
							private ServiceHost host;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public bool IsRunning
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								get { return host?.State == CommunicationState.Opened; }
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public BaseHost(string address, ILogger logger)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								this.address = address;
 | 
				
			||||||
 | 
								this.logger = logger;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public abstract IConnectResponse Connect(Guid? token = null);
 | 
				
			||||||
 | 
							public abstract void Disconnect(IMessage message);
 | 
				
			||||||
 | 
							public abstract IResponse Send(IMessage message);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public void Start()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								host = new ServiceHost(this);
 | 
				
			||||||
 | 
								host.AddServiceEndpoint(typeof(ICommunication), new NetNamedPipeBinding(NetNamedPipeSecurityMode.Transport), address);
 | 
				
			||||||
 | 
								host.Closed += Host_Closed;
 | 
				
			||||||
 | 
								host.Closing += Host_Closing;
 | 
				
			||||||
 | 
								host.Faulted += Host_Faulted;
 | 
				
			||||||
 | 
								host.Opened += Host_Opened;
 | 
				
			||||||
 | 
								host.Opening += Host_Opening;
 | 
				
			||||||
 | 
								host.UnknownMessageReceived += Host_UnknownMessageReceived;
 | 
				
			||||||
 | 
								host.Open();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								logger.Debug($"Successfully started communication host for endpoint '{address}'.");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public void Stop()
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								host?.Close();
 | 
				
			||||||
 | 
								logger.Debug($"Terminated communication host for endpoint '{address}'.");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void Host_Closed(object sender, EventArgs e)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								logger.Debug("Communication host has been closed.");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void Host_Closing(object sender, EventArgs e)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								logger.Debug("Communication host is closing...");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void Host_Faulted(object sender, EventArgs e)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								logger.Debug("Communication host has faulted!");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void Host_Opened(object sender, EventArgs e)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								logger.Debug("Communication host has been opened.");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void Host_Opening(object sender, EventArgs e)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								logger.Debug("Communication host is opening...");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void Host_UnknownMessageReceived(object sender, UnknownMessageReceivedEventArgs e)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								logger.Debug($"Communication host has received an unknown message: {e?.Message}.");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -23,7 +23,7 @@ namespace SafeExamBrowser.Core.Communication
 | 
				
			||||||
		protected Guid? CommunicationToken { get; private set; }
 | 
							protected Guid? CommunicationToken { get; private set; }
 | 
				
			||||||
		protected ILogger Logger { get; private set; }
 | 
							protected ILogger Logger { get; private set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public BaseProxy(ILogger logger, string address)
 | 
							public BaseProxy(string address, ILogger logger)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			this.address = address;
 | 
								this.address = address;
 | 
				
			||||||
			this.Logger = logger;
 | 
								this.Logger = logger;
 | 
				
			||||||
| 
						 | 
					@ -34,9 +34,11 @@ namespace SafeExamBrowser.Core.Communication
 | 
				
			||||||
			var endpoint = new EndpointAddress(address);
 | 
								var endpoint = new EndpointAddress(address);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			channel = ChannelFactory<ICommunication>.CreateChannel(new NetNamedPipeBinding(NetNamedPipeSecurityMode.Transport), endpoint);
 | 
								channel = ChannelFactory<ICommunication>.CreateChannel(new NetNamedPipeBinding(NetNamedPipeSecurityMode.Transport), endpoint);
 | 
				
			||||||
			(channel as ICommunicationObject).Closed += CommunicationHostProxy_Closed;
 | 
								(channel as ICommunicationObject).Closed += BaseProxy_Closed;
 | 
				
			||||||
			(channel as ICommunicationObject).Closing += CommunicationHostProxy_Closing;
 | 
								(channel as ICommunicationObject).Closing += BaseProxy_Closing;
 | 
				
			||||||
			(channel as ICommunicationObject).Faulted += CommunicationHostProxy_Faulted;
 | 
								(channel as ICommunicationObject).Faulted += BaseProxy_Faulted;
 | 
				
			||||||
 | 
								(channel as ICommunicationObject).Opened += BaseProxy_Opened;
 | 
				
			||||||
 | 
								(channel as ICommunicationObject).Opening += BaseProxy_Opening;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var response = channel.Connect(token);
 | 
								var response = channel.Connect(token);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -84,21 +86,31 @@ namespace SafeExamBrowser.Core.Communication
 | 
				
			||||||
			return channel != null && (channel as ICommunicationObject).State == CommunicationState.Opened;
 | 
								return channel != null && (channel as ICommunicationObject).State == CommunicationState.Opened;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private void CommunicationHostProxy_Closed(object sender, EventArgs e)
 | 
							private void BaseProxy_Closed(object sender, EventArgs e)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Logger.Debug("Communication channel has been closed.");
 | 
								Logger.Debug("Communication channel has been closed.");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private void CommunicationHostProxy_Closing(object sender, EventArgs e)
 | 
							private void BaseProxy_Closing(object sender, EventArgs e)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Logger.Debug("Communication channel is closing.");
 | 
								Logger.Debug("Communication channel is closing...");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private void CommunicationHostProxy_Faulted(object sender, EventArgs e)
 | 
							private void BaseProxy_Faulted(object sender, EventArgs e)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Logger.Debug("Communication channel has faulted!");
 | 
								Logger.Debug("Communication channel has faulted!");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void BaseProxy_Opened(object sender, EventArgs e)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Logger.Debug("Communication channel has been opened.");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private void BaseProxy_Opening(object sender, EventArgs e)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								Logger.Debug("Communication channel is opening...");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private string GetChannelState()
 | 
							private string GetChannelState()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			return channel == null ? "null" : $"in state '{(channel as ICommunicationObject).State}'";
 | 
								return channel == null ? "null" : $"in state '{(channel as ICommunicationObject).State}'";
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,7 +16,7 @@ namespace SafeExamBrowser.Core.Communication
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		public bool Ignore { private get; set; }
 | 
							public bool Ignore { private get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public ServiceProxy(ILogger logger, string address) : base(logger, address)
 | 
							public ServiceProxy(string address, ILogger logger) : base(address, logger)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,6 +60,9 @@
 | 
				
			||||||
  <Entry key="ProgressIndicator_InitializeWorkingArea">
 | 
					  <Entry key="ProgressIndicator_InitializeWorkingArea">
 | 
				
			||||||
    Initializing working area
 | 
					    Initializing working area
 | 
				
			||||||
  </Entry>
 | 
					  </Entry>
 | 
				
			||||||
 | 
					  <Entry key="ProgressIndicator_RestartCommunicationHost">
 | 
				
			||||||
 | 
					    Restarting communication host
 | 
				
			||||||
 | 
					  </Entry>
 | 
				
			||||||
  <Entry key="ProgressIndicator_RestoreWorkingArea">
 | 
					  <Entry key="ProgressIndicator_RestoreWorkingArea">
 | 
				
			||||||
    Restoring working area
 | 
					    Restoring working area
 | 
				
			||||||
  </Entry>
 | 
					  </Entry>
 | 
				
			||||||
| 
						 | 
					@ -69,6 +72,9 @@
 | 
				
			||||||
  <Entry key="ProgressIndicator_ShutdownProcedure">
 | 
					  <Entry key="ProgressIndicator_ShutdownProcedure">
 | 
				
			||||||
    Initiating shutdown procedure
 | 
					    Initiating shutdown procedure
 | 
				
			||||||
  </Entry>
 | 
					  </Entry>
 | 
				
			||||||
 | 
					  <Entry key="ProgressIndicator_StartCommunicationHost">
 | 
				
			||||||
 | 
					    Starting communication host
 | 
				
			||||||
 | 
					  </Entry>
 | 
				
			||||||
  <Entry key="ProgressIndicator_StartEventHandling">
 | 
					  <Entry key="ProgressIndicator_StartEventHandling">
 | 
				
			||||||
    Starting event handling
 | 
					    Starting event handling
 | 
				
			||||||
  </Entry>
 | 
					  </Entry>
 | 
				
			||||||
| 
						 | 
					@ -78,6 +84,9 @@
 | 
				
			||||||
  <Entry key="ProgressIndicator_StartMouseInterception">
 | 
					  <Entry key="ProgressIndicator_StartMouseInterception">
 | 
				
			||||||
    Starting mouse interception
 | 
					    Starting mouse interception
 | 
				
			||||||
  </Entry>
 | 
					  </Entry>
 | 
				
			||||||
 | 
					  <Entry key="ProgressIndicator_StopCommunicationHost">
 | 
				
			||||||
 | 
					    Stopping communication host
 | 
				
			||||||
 | 
					  </Entry>
 | 
				
			||||||
  <Entry key="ProgressIndicator_StopEventHandling">
 | 
					  <Entry key="ProgressIndicator_StopEventHandling">
 | 
				
			||||||
    Stopping event handling
 | 
					    Stopping event handling
 | 
				
			||||||
  </Entry>
 | 
					  </Entry>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,9 +55,11 @@
 | 
				
			||||||
    <Reference Include="System.Xml.Linq" />
 | 
					    <Reference Include="System.Xml.Linq" />
 | 
				
			||||||
  </ItemGroup>
 | 
					  </ItemGroup>
 | 
				
			||||||
  <ItemGroup>
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <Compile Include="Behaviour\Operations\CommunicationOperation.cs" />
 | 
				
			||||||
    <Compile Include="Behaviour\Operations\I18nOperation.cs" />
 | 
					    <Compile Include="Behaviour\Operations\I18nOperation.cs" />
 | 
				
			||||||
    <Compile Include="Behaviour\Operations\OperationSequence.cs" />
 | 
					    <Compile Include="Behaviour\Operations\OperationSequence.cs" />
 | 
				
			||||||
    <Compile Include="Communication\BaseProxy.cs" />
 | 
					    <Compile Include="Communication\BaseProxy.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Communication\BaseHost.cs" />
 | 
				
			||||||
    <Compile Include="Communication\Messages\Message.cs" />
 | 
					    <Compile Include="Communication\Messages\Message.cs" />
 | 
				
			||||||
    <Compile Include="Communication\ServiceProxy.cs" />
 | 
					    <Compile Include="Communication\ServiceProxy.cs" />
 | 
				
			||||||
    <Compile Include="Logging\DefaultLogFormatter.cs" />
 | 
					    <Compile Include="Logging\DefaultLogFormatter.cs" />
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,7 +24,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		private Mock<ILogger> logger;
 | 
							private Mock<ILogger> logger;
 | 
				
			||||||
		private Mock<IRuntimeInfo> info;
 | 
							private Mock<IRuntimeInfo> info;
 | 
				
			||||||
		private Mock<ISettingsRepository> repository;
 | 
							private Mock<IConfigurationRepository> repository;
 | 
				
			||||||
		private Mock<ISettings> settings;
 | 
							private Mock<ISettings> settings;
 | 
				
			||||||
		private Mock<IText> text;
 | 
							private Mock<IText> text;
 | 
				
			||||||
		private Mock<IUserInterfaceFactory> uiFactory;
 | 
							private Mock<IUserInterfaceFactory> uiFactory;
 | 
				
			||||||
| 
						 | 
					@ -35,7 +35,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			logger = new Mock<ILogger>();
 | 
								logger = new Mock<ILogger>();
 | 
				
			||||||
			info = new Mock<IRuntimeInfo>();
 | 
								info = new Mock<IRuntimeInfo>();
 | 
				
			||||||
			repository = new Mock<ISettingsRepository>();
 | 
								repository = new Mock<IConfigurationRepository>();
 | 
				
			||||||
			settings = new Mock<ISettings>();
 | 
								settings = new Mock<ISettings>();
 | 
				
			||||||
			text = new Mock<IText>();
 | 
								text = new Mock<IText>();
 | 
				
			||||||
			uiFactory = new Mock<IUserInterfaceFactory>();
 | 
								uiFactory = new Mock<IUserInterfaceFactory>();
 | 
				
			||||||
| 
						 | 
					@ -43,24 +43,24 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
 | 
				
			||||||
			info.SetupGet(i => i.AppDataFolder).Returns(@"C:\Not\Really\AppData");
 | 
								info.SetupGet(i => i.AppDataFolder).Returns(@"C:\Not\Really\AppData");
 | 
				
			||||||
			info.SetupGet(i => i.DefaultSettingsFileName).Returns("SettingsDummy.txt");
 | 
								info.SetupGet(i => i.DefaultSettingsFileName).Returns("SettingsDummy.txt");
 | 
				
			||||||
			info.SetupGet(i => i.ProgramDataFolder).Returns(@"C:\Not\Really\ProgramData");
 | 
								info.SetupGet(i => i.ProgramDataFolder).Returns(@"C:\Not\Really\ProgramData");
 | 
				
			||||||
			repository.Setup(r => r.Load(It.IsAny<Uri>())).Returns(settings.Object);
 | 
								repository.Setup(r => r.LoadSettings(It.IsAny<Uri>())).Returns(settings.Object);
 | 
				
			||||||
			repository.Setup(r => r.LoadDefaults()).Returns(settings.Object);
 | 
								repository.Setup(r => r.LoadDefaultSettings()).Returns(settings.Object);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[TestMethod]
 | 
							[TestMethod]
 | 
				
			||||||
		public void MustNotFailWithoutCommandLineArgs()
 | 
							public void MustNotFailWithoutCommandLineArgs()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			repository.Setup(r => r.LoadDefaults());
 | 
								repository.Setup(r => r.LoadDefaultSettings());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null);
 | 
								sut = new ConfigurationOperation(repository.Object, logger.Object, info.Object, text.Object, uiFactory.Object, null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, new string[] { });
 | 
								sut = new ConfigurationOperation(repository.Object, logger.Object, info.Object, text.Object, uiFactory.Object, new string[] { });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			repository.Verify(r => r.LoadDefaults(), Times.Exactly(2));
 | 
								repository.Verify(r => r.LoadDefaultSettings(), Times.Exactly(2));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[TestMethod]
 | 
							[TestMethod]
 | 
				
			||||||
| 
						 | 
					@ -68,7 +68,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			var path = @"an/invalid\path.'*%yolo/()";
 | 
								var path = @"an/invalid\path.'*%yolo/()";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, new [] { "blubb.exe", path });
 | 
								sut = new ConfigurationOperation(repository.Object, logger.Object, info.Object, text.Object, uiFactory.Object, new [] { "blubb.exe", path });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -82,11 +82,11 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
 | 
				
			||||||
			info.SetupGet(r => r.ProgramDataFolder).Returns(location);
 | 
								info.SetupGet(r => r.ProgramDataFolder).Returns(location);
 | 
				
			||||||
			info.SetupGet(r => r.AppDataFolder).Returns(location);
 | 
								info.SetupGet(r => r.AppDataFolder).Returns(location);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, new[] { "blubb.exe", path });
 | 
								sut = new ConfigurationOperation(repository.Object, logger.Object, info.Object, text.Object, uiFactory.Object, new[] { "blubb.exe", path });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			repository.Verify(r => r.Load(It.Is<Uri>(u => u.Equals(new Uri(path)))), Times.Once);
 | 
								repository.Verify(r => r.LoadSettings(It.Is<Uri>(u => u.Equals(new Uri(path)))), Times.Once);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[TestMethod]
 | 
							[TestMethod]
 | 
				
			||||||
| 
						 | 
					@ -97,11 +97,11 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
 | 
				
			||||||
			info.SetupGet(r => r.ProgramDataFolder).Returns(location);
 | 
								info.SetupGet(r => r.ProgramDataFolder).Returns(location);
 | 
				
			||||||
			info.SetupGet(r => r.AppDataFolder).Returns($@"{location}\WRONG");
 | 
								info.SetupGet(r => r.AppDataFolder).Returns($@"{location}\WRONG");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null);
 | 
								sut = new ConfigurationOperation(repository.Object, logger.Object, info.Object, text.Object, uiFactory.Object, null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			repository.Verify(r => r.Load(It.Is<Uri>(u => u.Equals(new Uri(Path.Combine(location, "SettingsDummy.txt"))))), Times.Once);
 | 
								repository.Verify(r => r.LoadSettings(It.Is<Uri>(u => u.Equals(new Uri(Path.Combine(location, "SettingsDummy.txt"))))), Times.Once);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[TestMethod]
 | 
							[TestMethod]
 | 
				
			||||||
| 
						 | 
					@ -111,21 +111,21 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			info.SetupGet(r => r.AppDataFolder).Returns(location);
 | 
								info.SetupGet(r => r.AppDataFolder).Returns(location);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null);
 | 
								sut = new ConfigurationOperation(repository.Object, logger.Object, info.Object, text.Object, uiFactory.Object, null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			repository.Verify(r => r.Load(It.Is<Uri>(u => u.Equals(new Uri(Path.Combine(location, "SettingsDummy.txt"))))), Times.Once);
 | 
								repository.Verify(r => r.LoadSettings(It.Is<Uri>(u => u.Equals(new Uri(Path.Combine(location, "SettingsDummy.txt"))))), Times.Once);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[TestMethod]
 | 
							[TestMethod]
 | 
				
			||||||
		public void MustFallbackToDefaultsAsLastPrio()
 | 
							public void MustFallbackToDefaultsAsLastPrio()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null);
 | 
								sut = new ConfigurationOperation(repository.Object, logger.Object, info.Object, text.Object, uiFactory.Object, null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			repository.Verify(r => r.LoadDefaults(), Times.Once);
 | 
								repository.Verify(r => r.LoadDefaultSettings(), Times.Once);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[TestMethod]
 | 
							[TestMethod]
 | 
				
			||||||
| 
						 | 
					@ -136,7 +136,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
 | 
				
			||||||
			info.SetupGet(r => r.ProgramDataFolder).Returns(location);
 | 
								info.SetupGet(r => r.ProgramDataFolder).Returns(location);
 | 
				
			||||||
			uiFactory.Setup(u => u.Show(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<MessageBoxAction>(), It.IsAny<MessageBoxIcon>())).Returns(MessageBoxResult.Yes);
 | 
								uiFactory.Setup(u => u.Show(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<MessageBoxAction>(), It.IsAny<MessageBoxIcon>())).Returns(MessageBoxResult.Yes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null);
 | 
								sut = new ConfigurationOperation(repository.Object, logger.Object, info.Object, text.Object, uiFactory.Object, null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -148,7 +148,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			uiFactory.Setup(u => u.Show(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<MessageBoxAction>(), It.IsAny<MessageBoxIcon>())).Returns(MessageBoxResult.No);
 | 
								uiFactory.Setup(u => u.Show(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<MessageBoxAction>(), It.IsAny<MessageBoxIcon>())).Returns(MessageBoxResult.No);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut = new ConfigurationOperation(logger.Object, info.Object, repository.Object, text.Object, uiFactory.Object, null);
 | 
								sut = new ConfigurationOperation(repository.Object, logger.Object, info.Object, text.Object, uiFactory.Object, null);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
 | 
				
			||||||
	public class KioskModeOperationTests
 | 
						public class KioskModeOperationTests
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		[TestMethod]
 | 
							[TestMethod]
 | 
				
			||||||
		public void Todo()
 | 
							public void TODO()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			Assert.Fail();
 | 
								Assert.Fail();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,6 +10,7 @@ using System;
 | 
				
			||||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
 | 
					using Microsoft.VisualStudio.TestTools.UnitTesting;
 | 
				
			||||||
using Moq;
 | 
					using Moq;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Communication;
 | 
					using SafeExamBrowser.Contracts.Communication;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Configuration;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Configuration.Settings;
 | 
					using SafeExamBrowser.Contracts.Configuration.Settings;
 | 
				
			||||||
using SafeExamBrowser.Contracts.I18n;
 | 
					using SafeExamBrowser.Contracts.I18n;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Logging;
 | 
					using SafeExamBrowser.Contracts.Logging;
 | 
				
			||||||
| 
						 | 
					@ -23,7 +24,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		private Mock<ILogger> logger;
 | 
							private Mock<ILogger> logger;
 | 
				
			||||||
		private Mock<IServiceProxy> service;
 | 
							private Mock<IServiceProxy> service;
 | 
				
			||||||
		private Mock<ISettingsRepository> settings;
 | 
							private Mock<IConfigurationRepository> configuration;
 | 
				
			||||||
		private Mock<IProgressIndicator> progressIndicator;
 | 
							private Mock<IProgressIndicator> progressIndicator;
 | 
				
			||||||
		private Mock<IText> text;
 | 
							private Mock<IText> text;
 | 
				
			||||||
		private ServiceOperation sut;
 | 
							private ServiceOperation sut;
 | 
				
			||||||
| 
						 | 
					@ -33,23 +34,23 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			logger = new Mock<ILogger>();
 | 
								logger = new Mock<ILogger>();
 | 
				
			||||||
			service = new Mock<IServiceProxy>();
 | 
								service = new Mock<IServiceProxy>();
 | 
				
			||||||
			settings = new Mock<ISettingsRepository>();
 | 
								configuration = new Mock<IConfigurationRepository>();
 | 
				
			||||||
			progressIndicator = new Mock<IProgressIndicator>();
 | 
								progressIndicator = new Mock<IProgressIndicator>();
 | 
				
			||||||
			text = new Mock<IText>();
 | 
								text = new Mock<IText>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut = new ServiceOperation(logger.Object, service.Object, settings.Object, text.Object);
 | 
								sut = new ServiceOperation(configuration.Object, logger.Object, service.Object, text.Object);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[TestMethod]
 | 
							[TestMethod]
 | 
				
			||||||
		public void MustConnectToService()
 | 
							public void MustConnectToService()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			service.Setup(s => s.Connect()).Returns(true);
 | 
								service.Setup(s => s.Connect()).Returns(true);
 | 
				
			||||||
			settings.SetupGet(s => s.Current.ServicePolicy).Returns(ServicePolicy.Mandatory);
 | 
								configuration.SetupGet(s => s.CurrentSettings.ServicePolicy).Returns(ServicePolicy.Mandatory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			service.Setup(s => s.Connect()).Returns(true);
 | 
								service.Setup(s => s.Connect()).Returns(true);
 | 
				
			||||||
			settings.SetupGet(s => s.Current.ServicePolicy).Returns(ServicePolicy.Optional);
 | 
								configuration.SetupGet(s => s.CurrentSettings.ServicePolicy).Returns(ServicePolicy.Optional);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,22 +61,22 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
 | 
				
			||||||
		public void MustNotFailIfServiceNotAvailable()
 | 
							public void MustNotFailIfServiceNotAvailable()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			service.Setup(s => s.Connect()).Returns(false);
 | 
								service.Setup(s => s.Connect()).Returns(false);
 | 
				
			||||||
			settings.SetupGet(s => s.Current.ServicePolicy).Returns(ServicePolicy.Mandatory);
 | 
								configuration.SetupGet(s => s.CurrentSettings.ServicePolicy).Returns(ServicePolicy.Mandatory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			service.Setup(s => s.Connect()).Returns(false);
 | 
								service.Setup(s => s.Connect()).Returns(false);
 | 
				
			||||||
			settings.SetupGet(s => s.Current.ServicePolicy).Returns(ServicePolicy.Optional);
 | 
								configuration.SetupGet(s => s.CurrentSettings.ServicePolicy).Returns(ServicePolicy.Optional);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			service.Setup(s => s.Connect()).Throws<Exception>();
 | 
								service.Setup(s => s.Connect()).Throws<Exception>();
 | 
				
			||||||
			settings.SetupGet(s => s.Current.ServicePolicy).Returns(ServicePolicy.Mandatory);
 | 
								configuration.SetupGet(s => s.CurrentSettings.ServicePolicy).Returns(ServicePolicy.Mandatory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			service.Setup(s => s.Connect()).Throws<Exception>();
 | 
								service.Setup(s => s.Connect()).Throws<Exception>();
 | 
				
			||||||
			settings.SetupGet(s => s.Current.ServicePolicy).Returns(ServicePolicy.Optional);
 | 
								configuration.SetupGet(s => s.CurrentSettings.ServicePolicy).Returns(ServicePolicy.Optional);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -84,7 +85,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
 | 
				
			||||||
		public void MustAbortIfServiceMandatoryAndNotAvailable()
 | 
							public void MustAbortIfServiceMandatoryAndNotAvailable()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			service.Setup(s => s.Connect()).Returns(false);
 | 
								service.Setup(s => s.Connect()).Returns(false);
 | 
				
			||||||
			settings.SetupGet(s => s.Current.ServicePolicy).Returns(ServicePolicy.Mandatory);
 | 
								configuration.SetupGet(s => s.CurrentSettings.ServicePolicy).Returns(ServicePolicy.Mandatory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -95,7 +96,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
 | 
				
			||||||
		public void MustNotAbortIfServiceOptionalAndNotAvailable()
 | 
							public void MustNotAbortIfServiceOptionalAndNotAvailable()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			service.Setup(s => s.Connect()).Returns(false);
 | 
								service.Setup(s => s.Connect()).Returns(false);
 | 
				
			||||||
			settings.SetupGet(s => s.Current.ServicePolicy).Returns(ServicePolicy.Optional);
 | 
								configuration.SetupGet(s => s.CurrentSettings.ServicePolicy).Returns(ServicePolicy.Optional);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -107,13 +108,13 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
 | 
				
			||||||
		public void MustDisconnectWhenReverting()
 | 
							public void MustDisconnectWhenReverting()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			service.Setup(s => s.Connect()).Returns(true);
 | 
								service.Setup(s => s.Connect()).Returns(true);
 | 
				
			||||||
			settings.SetupGet(s => s.Current.ServicePolicy).Returns(ServicePolicy.Mandatory);
 | 
								configuration.SetupGet(s => s.CurrentSettings.ServicePolicy).Returns(ServicePolicy.Mandatory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
			sut.Revert();
 | 
								sut.Revert();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			service.Setup(s => s.Connect()).Returns(true);
 | 
								service.Setup(s => s.Connect()).Returns(true);
 | 
				
			||||||
			settings.SetupGet(s => s.Current.ServicePolicy).Returns(ServicePolicy.Optional);
 | 
								configuration.SetupGet(s => s.CurrentSettings.ServicePolicy).Returns(ServicePolicy.Optional);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
			sut.Revert();
 | 
								sut.Revert();
 | 
				
			||||||
| 
						 | 
					@ -126,7 +127,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			service.Setup(s => s.Connect()).Returns(true);
 | 
								service.Setup(s => s.Connect()).Returns(true);
 | 
				
			||||||
			service.Setup(s => s.Disconnect()).Throws<Exception>();
 | 
								service.Setup(s => s.Disconnect()).Throws<Exception>();
 | 
				
			||||||
			settings.SetupGet(s => s.Current.ServicePolicy).Returns(ServicePolicy.Optional);
 | 
								configuration.SetupGet(s => s.CurrentSettings.ServicePolicy).Returns(ServicePolicy.Optional);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
			sut.Revert();
 | 
								sut.Revert();
 | 
				
			||||||
| 
						 | 
					@ -138,25 +139,25 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
 | 
				
			||||||
		public void MustNotDisconnnectIfNotAvailable()
 | 
							public void MustNotDisconnnectIfNotAvailable()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			service.Setup(s => s.Connect()).Returns(false);
 | 
								service.Setup(s => s.Connect()).Returns(false);
 | 
				
			||||||
			settings.SetupGet(s => s.Current.ServicePolicy).Returns(ServicePolicy.Mandatory);
 | 
								configuration.SetupGet(s => s.CurrentSettings.ServicePolicy).Returns(ServicePolicy.Mandatory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
			sut.Revert();
 | 
								sut.Revert();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			service.Setup(s => s.Connect()).Returns(false);
 | 
								service.Setup(s => s.Connect()).Returns(false);
 | 
				
			||||||
			settings.SetupGet(s => s.Current.ServicePolicy).Returns(ServicePolicy.Optional);
 | 
								configuration.SetupGet(s => s.CurrentSettings.ServicePolicy).Returns(ServicePolicy.Optional);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
			sut.Revert();
 | 
								sut.Revert();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			service.Setup(s => s.Connect()).Throws<Exception>();
 | 
								service.Setup(s => s.Connect()).Throws<Exception>();
 | 
				
			||||||
			settings.SetupGet(s => s.Current.ServicePolicy).Returns(ServicePolicy.Mandatory);
 | 
								configuration.SetupGet(s => s.CurrentSettings.ServicePolicy).Returns(ServicePolicy.Mandatory);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
			sut.Revert();
 | 
								sut.Revert();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			service.Setup(s => s.Connect()).Throws<Exception>();
 | 
								service.Setup(s => s.Connect()).Throws<Exception>();
 | 
				
			||||||
			settings.SetupGet(s => s.Current.ServicePolicy).Returns(ServicePolicy.Optional);
 | 
								configuration.SetupGet(s => s.CurrentSettings.ServicePolicy).Returns(ServicePolicy.Optional);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sut.Perform();
 | 
								sut.Perform();
 | 
				
			||||||
			sut.Revert();
 | 
								sut.Revert();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -19,9 +19,9 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	internal class ConfigurationOperation : IOperation
 | 
						internal class ConfigurationOperation : IOperation
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							private IConfigurationRepository repository;
 | 
				
			||||||
		private ILogger logger;
 | 
							private ILogger logger;
 | 
				
			||||||
		private IRuntimeInfo runtimeInfo;
 | 
							private IRuntimeInfo runtimeInfo;
 | 
				
			||||||
		private ISettingsRepository repository;
 | 
					 | 
				
			||||||
		private IText text;
 | 
							private IText text;
 | 
				
			||||||
		private IUserInterfaceFactory uiFactory;
 | 
							private IUserInterfaceFactory uiFactory;
 | 
				
			||||||
		private string[] commandLineArgs;
 | 
							private string[] commandLineArgs;
 | 
				
			||||||
| 
						 | 
					@ -30,16 +30,16 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
 | 
				
			||||||
		public IProgressIndicator ProgressIndicator { private get; set; }
 | 
							public IProgressIndicator ProgressIndicator { private get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public ConfigurationOperation(
 | 
							public ConfigurationOperation(
 | 
				
			||||||
 | 
								IConfigurationRepository repository,
 | 
				
			||||||
			ILogger logger,
 | 
								ILogger logger,
 | 
				
			||||||
			IRuntimeInfo runtimeInfo,
 | 
								IRuntimeInfo runtimeInfo,
 | 
				
			||||||
			ISettingsRepository repository,
 | 
					 | 
				
			||||||
			IText text,
 | 
								IText text,
 | 
				
			||||||
			IUserInterfaceFactory uiFactory,
 | 
								IUserInterfaceFactory uiFactory,
 | 
				
			||||||
			string[] commandLineArgs)
 | 
								string[] commandLineArgs)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								this.repository = repository;
 | 
				
			||||||
			this.logger = logger;
 | 
								this.logger = logger;
 | 
				
			||||||
			this.commandLineArgs = commandLineArgs;
 | 
								this.commandLineArgs = commandLineArgs;
 | 
				
			||||||
			this.repository = repository;
 | 
					 | 
				
			||||||
			this.runtimeInfo = runtimeInfo;
 | 
								this.runtimeInfo = runtimeInfo;
 | 
				
			||||||
			this.text = text;
 | 
								this.text = text;
 | 
				
			||||||
			this.uiFactory = uiFactory;
 | 
								this.uiFactory = uiFactory;
 | 
				
			||||||
| 
						 | 
					@ -56,7 +56,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
 | 
				
			||||||
			if (isValidUri)
 | 
								if (isValidUri)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				logger.Info($"Loading configuration from '{uri.AbsolutePath}'...");
 | 
									logger.Info($"Loading configuration from '{uri.AbsolutePath}'...");
 | 
				
			||||||
				settings = repository.Load(uri);
 | 
									settings = repository.LoadSettings(uri);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (settings.ConfigurationMode == ConfigurationMode.ConfigureClient && UserWantsToAbortStartup())
 | 
									if (settings.ConfigurationMode == ConfigurationMode.ConfigureClient && UserWantsToAbortStartup())
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
| 
						 | 
					@ -67,7 +67,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				logger.Info("No valid settings file specified nor found in PROGRAMDATA or APPDATA - loading default settings...");
 | 
									logger.Info("No valid settings file specified nor found in PROGRAMDATA or APPDATA - loading default settings...");
 | 
				
			||||||
				settings = repository.LoadDefaults();
 | 
									settings = repository.LoadDefaultSettings();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using SafeExamBrowser.Contracts.Behaviour.Operations;
 | 
					using SafeExamBrowser.Contracts.Behaviour.Operations;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Configuration;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Configuration.Settings;
 | 
					using SafeExamBrowser.Contracts.Configuration.Settings;
 | 
				
			||||||
using SafeExamBrowser.Contracts.I18n;
 | 
					using SafeExamBrowser.Contracts.I18n;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Logging;
 | 
					using SafeExamBrowser.Contracts.Logging;
 | 
				
			||||||
| 
						 | 
					@ -17,21 +18,21 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
 | 
				
			||||||
	internal class KioskModeOperation : IOperation
 | 
						internal class KioskModeOperation : IOperation
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		private ILogger logger;
 | 
							private ILogger logger;
 | 
				
			||||||
		private ISettingsRepository settingsRepository;
 | 
							private IConfigurationRepository configuration;
 | 
				
			||||||
		private KioskMode kioskMode;
 | 
							private KioskMode kioskMode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public bool Abort { get; private set; }
 | 
							public bool Abort { get; private set; }
 | 
				
			||||||
		public IProgressIndicator ProgressIndicator { private get; set; }
 | 
							public IProgressIndicator ProgressIndicator { private get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public KioskModeOperation(ILogger logger, ISettingsRepository settingsRepository)
 | 
							public KioskModeOperation(ILogger logger, IConfigurationRepository configuration)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			this.logger = logger;
 | 
								this.logger = logger;
 | 
				
			||||||
			this.settingsRepository = settingsRepository;
 | 
								this.configuration = configuration;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public void Perform()
 | 
							public void Perform()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			kioskMode = settingsRepository.Current.KioskMode;
 | 
								kioskMode = configuration.CurrentSettings.KioskMode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			logger.Info($"Initializing kiosk mode '{kioskMode}'...");
 | 
								logger.Info($"Initializing kiosk mode '{kioskMode}'...");
 | 
				
			||||||
			ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeKioskMode);
 | 
								ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeKioskMode);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,7 @@
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Behaviour.Operations;
 | 
					using SafeExamBrowser.Contracts.Behaviour.Operations;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Communication;
 | 
					using SafeExamBrowser.Contracts.Communication;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Configuration;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Configuration.Settings;
 | 
					using SafeExamBrowser.Contracts.Configuration.Settings;
 | 
				
			||||||
using SafeExamBrowser.Contracts.I18n;
 | 
					using SafeExamBrowser.Contracts.I18n;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Logging;
 | 
					using SafeExamBrowser.Contracts.Logging;
 | 
				
			||||||
| 
						 | 
					@ -20,19 +21,19 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		private bool serviceAvailable;
 | 
							private bool serviceAvailable;
 | 
				
			||||||
		private bool serviceMandatory;
 | 
							private bool serviceMandatory;
 | 
				
			||||||
 | 
							private IConfigurationRepository configuration;
 | 
				
			||||||
		private ILogger logger;
 | 
							private ILogger logger;
 | 
				
			||||||
		private IServiceProxy service;
 | 
							private IServiceProxy service;
 | 
				
			||||||
		private ISettingsRepository settingsRepository;
 | 
					 | 
				
			||||||
		private IText text;
 | 
							private IText text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public bool Abort { get; private set; }
 | 
							public bool Abort { get; private set; }
 | 
				
			||||||
		public IProgressIndicator ProgressIndicator { private get; set; }
 | 
							public IProgressIndicator ProgressIndicator { private get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public ServiceOperation(ILogger logger, IServiceProxy service, ISettingsRepository settingsRepository, IText text)
 | 
							public ServiceOperation(IConfigurationRepository configuration, ILogger logger, IServiceProxy service, IText text)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								this.configuration = configuration;
 | 
				
			||||||
			this.service = service;
 | 
								this.service = service;
 | 
				
			||||||
			this.logger = logger;
 | 
								this.logger = logger;
 | 
				
			||||||
			this.settingsRepository = settingsRepository;
 | 
					 | 
				
			||||||
			this.text = text;
 | 
								this.text = text;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,7 +44,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			try
 | 
								try
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				serviceMandatory = settingsRepository.Current.ServicePolicy == ServicePolicy.Mandatory;
 | 
									serviceMandatory = configuration.CurrentSettings.ServicePolicy == ServicePolicy.Mandatory;
 | 
				
			||||||
				serviceAvailable = service.Connect();
 | 
									serviceAvailable = service.Connect();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			catch (Exception e)
 | 
								catch (Exception e)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,36 +20,41 @@ namespace SafeExamBrowser.Runtime.Behaviour
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	internal class RuntimeController : IRuntimeController
 | 
						internal class RuntimeController : IRuntimeController
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							private bool initialized;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							private IConfigurationRepository configuration;
 | 
				
			||||||
		private ILogger logger;
 | 
							private ILogger logger;
 | 
				
			||||||
		private IOperationSequence bootstrapSequence;
 | 
							private IOperationSequence bootstrapSequence;
 | 
				
			||||||
		private IOperationSequence sessionSequence;
 | 
							private IOperationSequence sessionSequence;
 | 
				
			||||||
 | 
							private IRuntimeHost runtimeHost;
 | 
				
			||||||
		private IRuntimeInfo runtimeInfo;
 | 
							private IRuntimeInfo runtimeInfo;
 | 
				
			||||||
		private IRuntimeWindow runtimeWindow;
 | 
							private IRuntimeWindow runtimeWindow;
 | 
				
			||||||
		private IServiceProxy serviceProxy;
 | 
							private IServiceProxy serviceProxy;
 | 
				
			||||||
		private ISettingsRepository settingsRepository;
 | 
					 | 
				
			||||||
		private ISplashScreen splashScreen;
 | 
							private ISplashScreen splashScreen;
 | 
				
			||||||
		private Action terminationCallback;
 | 
							private Action shutdown;
 | 
				
			||||||
		private IText text;
 | 
							private IText text;
 | 
				
			||||||
		private IUserInterfaceFactory uiFactory;
 | 
							private IUserInterfaceFactory uiFactory;
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		public RuntimeController(
 | 
							public RuntimeController(
 | 
				
			||||||
 | 
								IConfigurationRepository configuration,
 | 
				
			||||||
			ILogger logger,
 | 
								ILogger logger,
 | 
				
			||||||
			IOperationSequence bootstrapSequence,
 | 
								IOperationSequence bootstrapSequence,
 | 
				
			||||||
			IOperationSequence sessionSequence,
 | 
								IOperationSequence sessionSequence,
 | 
				
			||||||
 | 
								IRuntimeHost runtimeHost,
 | 
				
			||||||
			IRuntimeInfo runtimeInfo,
 | 
								IRuntimeInfo runtimeInfo,
 | 
				
			||||||
			IServiceProxy serviceProxy,
 | 
								IServiceProxy serviceProxy,
 | 
				
			||||||
			ISettingsRepository settingsRepository,
 | 
								Action shutdown,
 | 
				
			||||||
			Action terminationCallback,
 | 
					 | 
				
			||||||
			IText text,
 | 
								IText text,
 | 
				
			||||||
			IUserInterfaceFactory uiFactory)
 | 
								IUserInterfaceFactory uiFactory)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								this.configuration = configuration;
 | 
				
			||||||
			this.logger = logger;
 | 
								this.logger = logger;
 | 
				
			||||||
			this.bootstrapSequence = bootstrapSequence;
 | 
								this.bootstrapSequence = bootstrapSequence;
 | 
				
			||||||
			this.sessionSequence = sessionSequence;
 | 
								this.sessionSequence = sessionSequence;
 | 
				
			||||||
 | 
								this.runtimeHost = runtimeHost;
 | 
				
			||||||
			this.runtimeInfo = runtimeInfo;
 | 
								this.runtimeInfo = runtimeInfo;
 | 
				
			||||||
			this.serviceProxy = serviceProxy;
 | 
								this.serviceProxy = serviceProxy;
 | 
				
			||||||
			this.settingsRepository = settingsRepository;
 | 
								this.shutdown = shutdown;
 | 
				
			||||||
			this.terminationCallback = terminationCallback;
 | 
					 | 
				
			||||||
			this.text = text;
 | 
								this.text = text;
 | 
				
			||||||
			this.uiFactory = uiFactory;
 | 
								this.uiFactory = uiFactory;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -58,19 +63,16 @@ namespace SafeExamBrowser.Runtime.Behaviour
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			logger.Info("--- Initiating startup procedure ---");
 | 
								logger.Info("--- Initiating startup procedure ---");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								runtimeWindow = uiFactory.CreateRuntimeWindow(runtimeInfo, text);
 | 
				
			||||||
			splashScreen = uiFactory.CreateSplashScreen(runtimeInfo, text);
 | 
								splashScreen = uiFactory.CreateSplashScreen(runtimeInfo, text);
 | 
				
			||||||
			splashScreen.Show();
 | 
								splashScreen.Show();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			bootstrapSequence.ProgressIndicator = splashScreen;
 | 
								bootstrapSequence.ProgressIndicator = splashScreen;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var success = bootstrapSequence.TryPerform();
 | 
								initialized = bootstrapSequence.TryPerform();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			System.Threading.Thread.Sleep(5000);
 | 
								if (initialized)
 | 
				
			||||||
 | 
					 | 
				
			||||||
			if (success)
 | 
					 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				runtimeWindow = uiFactory.CreateRuntimeWindow(runtimeInfo, text);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				logger.Info("--- Application successfully initialized! ---");
 | 
									logger.Info("--- Application successfully initialized! ---");
 | 
				
			||||||
				logger.Log(string.Empty);
 | 
									logger.Log(string.Empty);
 | 
				
			||||||
				logger.Subscribe(runtimeWindow);
 | 
									logger.Subscribe(runtimeWindow);
 | 
				
			||||||
| 
						 | 
					@ -85,17 +87,19 @@ namespace SafeExamBrowser.Runtime.Behaviour
 | 
				
			||||||
				logger.Log(string.Empty);
 | 
									logger.Log(string.Empty);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return success;
 | 
								return initialized;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		public void Terminate()
 | 
							public void Terminate()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			StopSession();
 | 
								// TODO: Necessary here? Move to App.cs as private "started" flag if not...
 | 
				
			||||||
 | 
								if (!initialized)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// TODO:
 | 
								// TODO: Only if session is running!
 | 
				
			||||||
			// - Disconnect from service
 | 
								StopSession();
 | 
				
			||||||
			// - Terminate runtime communication host
 | 
					 | 
				
			||||||
			// - Revert kiosk mode (or do that when stopping session?)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			logger.Unsubscribe(runtimeWindow);
 | 
								logger.Unsubscribe(runtimeWindow);
 | 
				
			||||||
			runtimeWindow?.Close();
 | 
								runtimeWindow?.Close();
 | 
				
			||||||
| 
						 | 
					@ -104,6 +108,10 @@ namespace SafeExamBrowser.Runtime.Behaviour
 | 
				
			||||||
			logger.Log(string.Empty);
 | 
								logger.Log(string.Empty);
 | 
				
			||||||
			logger.Info("--- Initiating shutdown procedure ---");
 | 
								logger.Info("--- Initiating shutdown procedure ---");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// TODO:
 | 
				
			||||||
 | 
								// - Disconnect from service
 | 
				
			||||||
 | 
								// - Terminate runtime communication host
 | 
				
			||||||
 | 
								// - Revert kiosk mode (or do that when stopping session?)
 | 
				
			||||||
			var success = bootstrapSequence.TryRevert();
 | 
								var success = bootstrapSequence.TryRevert();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (success)
 | 
								if (success)
 | 
				
			||||||
| 
						 | 
					@ -137,25 +145,28 @@ namespace SafeExamBrowser.Runtime.Behaviour
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (success)
 | 
								if (success)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
 | 
									// TODO
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
 | 
									// TODO
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// TODO: Remove!
 | 
				
			||||||
			System.Threading.Thread.Sleep(5000);
 | 
								System.Threading.Thread.Sleep(5000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								runtimeWindow.HideProgressBar();
 | 
				
			||||||
			runtimeWindow.UpdateText(TextKey.RuntimeWindow_ApplicationRunning);
 | 
								runtimeWindow.UpdateText(TextKey.RuntimeWindow_ApplicationRunning);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (settingsRepository.Current.KioskMode == KioskMode.DisableExplorerShell)
 | 
								if (configuration.CurrentSettings.KioskMode == KioskMode.DisableExplorerShell)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				runtimeWindow.Hide();
 | 
									runtimeWindow.Hide();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// TODO: Remove!
 | 
				
			||||||
			System.Threading.Thread.Sleep(5000);
 | 
								System.Threading.Thread.Sleep(5000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			terminationCallback.Invoke();
 | 
								shutdown.Invoke();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private void StopSession()
 | 
							private void StopSession()
 | 
				
			||||||
| 
						 | 
					@ -163,12 +174,26 @@ namespace SafeExamBrowser.Runtime.Behaviour
 | 
				
			||||||
			logger.Info("Stopping current session...");
 | 
								logger.Info("Stopping current session...");
 | 
				
			||||||
			runtimeWindow.Show();
 | 
								runtimeWindow.Show();
 | 
				
			||||||
			runtimeWindow.BringToForeground();
 | 
								runtimeWindow.BringToForeground();
 | 
				
			||||||
 | 
								runtimeWindow.ShowProgressBar();
 | 
				
			||||||
			runtimeWindow.UpdateText(TextKey.RuntimeWindow_StopSession, true);
 | 
								runtimeWindow.UpdateText(TextKey.RuntimeWindow_StopSession, true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// TODO:
 | 
								// TODO:
 | 
				
			||||||
			// - Terminate client (or does it terminate itself?)
 | 
								// - Terminate client (or does it terminate itself?)
 | 
				
			||||||
			// - Finalize session with service
 | 
								// - Finalize session with service
 | 
				
			||||||
			// - Stop event handling and close session
 | 
								// - Stop event handling and close session
 | 
				
			||||||
 | 
								var success = sessionSequence.TryRevert();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// TODO: Remove!
 | 
				
			||||||
 | 
								System.Threading.Thread.Sleep(5000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (success)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									// TODO
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									// TODO
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										42
									
								
								SafeExamBrowser.Runtime/Communication/RuntimeHost.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								SafeExamBrowser.Runtime/Communication/RuntimeHost.cs
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,42 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2018 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 SafeExamBrowser.Contracts.Communication;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Communication.Messages;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Communication.Responses;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Contracts.Logging;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Core.Communication;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace SafeExamBrowser.Runtime.Communication
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						internal class RuntimeHost : BaseHost, IRuntimeHost
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							public RuntimeHost(string address, ILogger logger) : base(address, logger)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public override IConnectResponse Connect(Guid? token = null)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								// TODO
 | 
				
			||||||
 | 
								throw new NotImplementedException();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public override void Disconnect(IMessage message)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								// TODO
 | 
				
			||||||
 | 
								throw new NotImplementedException();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							public override IResponse Send(IMessage message)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								// TODO
 | 
				
			||||||
 | 
								throw new NotImplementedException();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -8,11 +8,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using System;
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.IO;
 | 
					 | 
				
			||||||
using System.Reflection;
 | 
					 | 
				
			||||||
using System.Windows;
 | 
					using System.Windows;
 | 
				
			||||||
using SafeExamBrowser.Configuration;
 | 
					using SafeExamBrowser.Configuration;
 | 
				
			||||||
using SafeExamBrowser.Configuration.Settings;
 | 
					 | 
				
			||||||
using SafeExamBrowser.Contracts.Behaviour;
 | 
					using SafeExamBrowser.Contracts.Behaviour;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Behaviour.Operations;
 | 
					using SafeExamBrowser.Contracts.Behaviour.Operations;
 | 
				
			||||||
using SafeExamBrowser.Contracts.Configuration;
 | 
					using SafeExamBrowser.Contracts.Configuration;
 | 
				
			||||||
| 
						 | 
					@ -23,6 +20,7 @@ using SafeExamBrowser.Core.I18n;
 | 
				
			||||||
using SafeExamBrowser.Core.Logging;
 | 
					using SafeExamBrowser.Core.Logging;
 | 
				
			||||||
using SafeExamBrowser.Runtime.Behaviour;
 | 
					using SafeExamBrowser.Runtime.Behaviour;
 | 
				
			||||||
using SafeExamBrowser.Runtime.Behaviour.Operations;
 | 
					using SafeExamBrowser.Runtime.Behaviour.Operations;
 | 
				
			||||||
 | 
					using SafeExamBrowser.Runtime.Communication;
 | 
				
			||||||
using SafeExamBrowser.UserInterface.Classic;
 | 
					using SafeExamBrowser.UserInterface.Classic;
 | 
				
			||||||
using SafeExamBrowser.WindowsApi;
 | 
					using SafeExamBrowser.WindowsApi;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,7 +29,7 @@ namespace SafeExamBrowser.Runtime
 | 
				
			||||||
	internal class CompositionRoot
 | 
						internal class CompositionRoot
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		private ILogger logger;
 | 
							private ILogger logger;
 | 
				
			||||||
		private RuntimeInfo runtimeInfo;
 | 
							private IRuntimeInfo runtimeInfo;
 | 
				
			||||||
		private ISystemInfo systemInfo;
 | 
							private ISystemInfo systemInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal IRuntimeController RuntimeController { get; private set; }
 | 
							internal IRuntimeController RuntimeController { get; private set; }
 | 
				
			||||||
| 
						 | 
					@ -42,30 +40,30 @@ namespace SafeExamBrowser.Runtime
 | 
				
			||||||
			var bootstrapOperations = new Queue<IOperation>();
 | 
								var bootstrapOperations = new Queue<IOperation>();
 | 
				
			||||||
			var sessionOperations = new Queue<IOperation>();
 | 
								var sessionOperations = new Queue<IOperation>();
 | 
				
			||||||
			var nativeMethods = new NativeMethods();
 | 
								var nativeMethods = new NativeMethods();
 | 
				
			||||||
			var settingsRepository = new SettingsRepository();
 | 
								var configuration = new ConfigurationRepository();
 | 
				
			||||||
			var uiFactory = new UserInterfaceFactory();
 | 
								var uiFactory = new UserInterfaceFactory();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			logger = new Logger();
 | 
								logger = new Logger();
 | 
				
			||||||
			runtimeInfo = new RuntimeInfo();
 | 
								runtimeInfo = configuration.RuntimeInfo;
 | 
				
			||||||
			systemInfo = new SystemInfo();
 | 
								systemInfo = new SystemInfo();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			InitializeRuntimeInfo();
 | 
					 | 
				
			||||||
			InitializeLogging();
 | 
								InitializeLogging();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var text = new Text(logger);
 | 
								var text = new Text(logger);
 | 
				
			||||||
			var serviceProxy = new ServiceProxy(new ModuleLogger(logger, typeof(ServiceProxy)), "net.pipe://localhost/safeexambrowser/service");
 | 
								var runtimeHost = new RuntimeHost(runtimeInfo.RuntimeAddress, new ModuleLogger(logger, typeof(RuntimeHost)));
 | 
				
			||||||
 | 
								var serviceProxy = new ServiceProxy(runtimeInfo.ServiceAddress, new ModuleLogger(logger, typeof(ServiceProxy)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			bootstrapOperations.Enqueue(new I18nOperation(logger, text));
 | 
								bootstrapOperations.Enqueue(new I18nOperation(logger, text));
 | 
				
			||||||
			// TODO: RuntimeHostOperation here (is IBootstrapOperation -> only performed once per runtime!)
 | 
								bootstrapOperations.Enqueue(new CommunicationOperation(runtimeHost, logger));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			sessionOperations.Enqueue(new ConfigurationOperation(logger, runtimeInfo, settingsRepository, text, uiFactory, args));
 | 
								sessionOperations.Enqueue(new ConfigurationOperation(configuration, logger, runtimeInfo, text, uiFactory, args));
 | 
				
			||||||
			sessionOperations.Enqueue(new ServiceOperation(logger, serviceProxy, settingsRepository, text));
 | 
								sessionOperations.Enqueue(new ServiceOperation(configuration, logger, serviceProxy, text));
 | 
				
			||||||
			sessionOperations.Enqueue(new KioskModeOperation(logger, settingsRepository));
 | 
								sessionOperations.Enqueue(new KioskModeOperation(logger, configuration));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var bootstrapSequence = new OperationSequence(logger, bootstrapOperations);
 | 
								var boostrapSequence = new OperationSequence(logger, bootstrapOperations);
 | 
				
			||||||
			var sessionSequence = new OperationSequence(logger, sessionOperations);
 | 
								var sessionSequence = new OperationSequence(logger, sessionOperations);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			RuntimeController = new RuntimeController(logger, bootstrapSequence, sessionSequence, runtimeInfo, serviceProxy, settingsRepository, Application.Current.Shutdown, text, uiFactory);
 | 
								RuntimeController = new RuntimeController(configuration, logger, boostrapSequence, sessionSequence, runtimeHost, runtimeInfo, serviceProxy, Application.Current.Shutdown, text, uiFactory);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal void LogStartupInformation()
 | 
							internal void LogStartupInformation()
 | 
				
			||||||
| 
						 | 
					@ -84,28 +82,7 @@ namespace SafeExamBrowser.Runtime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		internal void LogShutdownInformation()
 | 
							internal void LogShutdownInformation()
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			logger?.Log($"{Environment.NewLine}# Application terminated at {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
 | 
								logger?.Log($"# Application terminated at {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}");
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		private void InitializeRuntimeInfo()
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			var appDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), nameof(SafeExamBrowser));
 | 
					 | 
				
			||||||
			var executable = Assembly.GetEntryAssembly();
 | 
					 | 
				
			||||||
			var startTime = DateTime.Now;
 | 
					 | 
				
			||||||
			var logFolder = Path.Combine(appDataFolder, "Logs");
 | 
					 | 
				
			||||||
			var logFilePrefix = startTime.ToString("yyyy-MM-dd\\_HH\\hmm\\mss\\s");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			runtimeInfo.ApplicationStartTime = startTime;
 | 
					 | 
				
			||||||
			runtimeInfo.AppDataFolder = appDataFolder;
 | 
					 | 
				
			||||||
			runtimeInfo.BrowserCachePath = Path.Combine(appDataFolder, "Cache");
 | 
					 | 
				
			||||||
			runtimeInfo.BrowserLogFile = Path.Combine(logFolder, $"{logFilePrefix}_Browser.txt");
 | 
					 | 
				
			||||||
			runtimeInfo.ClientLogFile = Path.Combine(logFolder, $"{logFilePrefix}_Client.txt");
 | 
					 | 
				
			||||||
			runtimeInfo.DefaultSettingsFileName = "SebClientSettings.seb";
 | 
					 | 
				
			||||||
			runtimeInfo.ProgramCopyright = executable.GetCustomAttribute<AssemblyCopyrightAttribute>().Copyright;
 | 
					 | 
				
			||||||
			runtimeInfo.ProgramDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), nameof(SafeExamBrowser));
 | 
					 | 
				
			||||||
			runtimeInfo.ProgramTitle = executable.GetCustomAttribute<AssemblyTitleAttribute>().Title;
 | 
					 | 
				
			||||||
			runtimeInfo.ProgramVersion = executable.GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;
 | 
					 | 
				
			||||||
			runtimeInfo.RuntimeLogFile = Path.Combine(logFolder, $"{logFilePrefix}_Runtime.txt");
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		private void InitializeLogging()
 | 
							private void InitializeLogging()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -90,6 +90,7 @@
 | 
				
			||||||
    <Compile Include="Behaviour\Operations\ConfigurationOperation.cs" />
 | 
					    <Compile Include="Behaviour\Operations\ConfigurationOperation.cs" />
 | 
				
			||||||
    <Compile Include="Behaviour\Operations\KioskModeOperation.cs" />
 | 
					    <Compile Include="Behaviour\Operations\KioskModeOperation.cs" />
 | 
				
			||||||
    <Compile Include="Behaviour\Operations\ServiceOperation.cs" />
 | 
					    <Compile Include="Behaviour\Operations\ServiceOperation.cs" />
 | 
				
			||||||
 | 
					    <Compile Include="Communication\RuntimeHost.cs" />
 | 
				
			||||||
    <Compile Include="CompositionRoot.cs" />
 | 
					    <Compile Include="CompositionRoot.cs" />
 | 
				
			||||||
    <Compile Include="Properties\AssemblyInfo.cs">
 | 
					    <Compile Include="Properties\AssemblyInfo.cs">
 | 
				
			||||||
      <SubType>Code</SubType>
 | 
					      <SubType>Code</SubType>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue