SEBWIN-220: Replaced guid with abstact InstanceIdentifier for application instances and started to implement logging for browser component.
This commit is contained in:
		
							parent
							
								
									d521e2d3c0
								
							
						
					
					
						commit
						ef31db9920
					
				
					 22 changed files with 159 additions and 48 deletions
				
			
		|  | @ -24,6 +24,8 @@ namespace SafeExamBrowser.Browser | |||
| { | ||||
| 	public class BrowserApplicationController : IBrowserApplicationController | ||||
| 	{ | ||||
| 		private int instanceIdCounter = default(int); | ||||
| 
 | ||||
| 		private AppConfig appConfig; | ||||
| 		private IApplicationButton button; | ||||
| 		private IList<IApplicationInstance> instances; | ||||
|  | @ -57,6 +59,8 @@ namespace SafeExamBrowser.Browser | |||
| 			var cefSettings = InitializeCefSettings(); | ||||
| 			var success = Cef.Initialize(cefSettings, true, null); | ||||
| 
 | ||||
| 			logger.Info("Initialized CEF."); | ||||
| 
 | ||||
| 			if (!success) | ||||
| 			{ | ||||
| 				throw new Exception("Failed to initialize the browser engine!"); | ||||
|  | @ -75,14 +79,20 @@ namespace SafeExamBrowser.Browser | |||
| 			{ | ||||
| 				instance.Terminated -= Instance_Terminated; | ||||
| 				instance.Window.Close(); | ||||
| 
 | ||||
| 				logger.Info($"Terminated browser instance {instance.Id}."); | ||||
| 			} | ||||
| 
 | ||||
| 			Cef.Shutdown(); | ||||
| 
 | ||||
| 			logger.Info("Terminated CEF."); | ||||
| 		} | ||||
| 
 | ||||
| 		private void CreateNewInstance() | ||||
| 		{ | ||||
| 			var instance = new BrowserApplicationInstance(appConfig, settings, text, uiFactory, instances.Count == 0); | ||||
| 			var id = new BrowserInstanceIdentifier(++instanceIdCounter); | ||||
| 			var isMainInstance = instances.Count == 0; | ||||
| 			var instance = new BrowserApplicationInstance(appConfig, settings, id, isMainInstance, text, uiFactory); | ||||
| 
 | ||||
| 			instance.Initialize(); | ||||
| 			instance.ConfigurationDownloadRequested += (fileName, args) => ConfigurationDownloadRequested?.Invoke(fileName, args); | ||||
|  | @ -91,36 +101,44 @@ namespace SafeExamBrowser.Browser | |||
| 			button.RegisterInstance(instance); | ||||
| 			instances.Add(instance); | ||||
| 			instance.Window.Show(); | ||||
| 
 | ||||
| 			logger.Info($"Created browser instance {instance.Id}."); | ||||
| 		} | ||||
| 
 | ||||
| 		private CefSettings InitializeCefSettings() | ||||
| 		{ | ||||
| 			var warning = appConfig.LogLevel == LogLevel.Warning; | ||||
| 			var error = appConfig.LogLevel == LogLevel.Error; | ||||
| 			var cefSettings = new CefSettings | ||||
| 			{ | ||||
| 				CachePath = appConfig.BrowserCachePath, | ||||
| 				LogFile = appConfig.BrowserLogFile, | ||||
| 				// TODO: Set according to current application LogLevel, but avoid verbose! | ||||
| 				LogSeverity = LogSeverity.Info | ||||
| 				LogSeverity = error ? LogSeverity.Error : (warning ? LogSeverity.Warning : LogSeverity.Info) | ||||
| 			}; | ||||
| 
 | ||||
| 			logger.Debug($"CEF cache path is '{cefSettings.CachePath}'."); | ||||
| 			logger.Debug($"CEF log file is '{cefSettings.LogFile}'."); | ||||
| 			logger.Debug($"CEF log severity is '{cefSettings.LogSeverity}'."); | ||||
| 
 | ||||
| 			return cefSettings; | ||||
| 		} | ||||
| 
 | ||||
| 		private void Button_OnClick(Guid? instanceId = null) | ||||
| 		private void Button_OnClick(InstanceIdentifier id = null) | ||||
| 		{ | ||||
| 			if (instanceId.HasValue) | ||||
| 			{ | ||||
| 				instances.FirstOrDefault(i => i.Id == instanceId)?.Window?.BringToForeground(); | ||||
| 			} | ||||
| 			else | ||||
| 			if (id is null) | ||||
| 			{ | ||||
| 				CreateNewInstance(); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				instances.FirstOrDefault(i => i.Id == id)?.Window?.BringToForeground(); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		private void Instance_Terminated(Guid id) | ||||
| 		private void Instance_Terminated(InstanceIdentifier id) | ||||
| 		{ | ||||
| 			instances.Remove(instances.FirstOrDefault(i => i.Id == id)); | ||||
| 			logger.Info($"Browser instance {id} was terminated."); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -6,7 +6,6 @@ | |||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  */ | ||||
| 
 | ||||
| using System; | ||||
| using SafeExamBrowser.Browser.Handlers; | ||||
| using SafeExamBrowser.Contracts.Behaviour; | ||||
| using SafeExamBrowser.Contracts.Behaviour.Events; | ||||
|  | @ -30,7 +29,7 @@ namespace SafeExamBrowser.Browser | |||
| 		private IText text; | ||||
| 		private IUserInterfaceFactory uiFactory; | ||||
| 
 | ||||
| 		public Guid Id { get; private set; } | ||||
| 		public InstanceIdentifier Id { get; private set; } | ||||
| 		public string Name { get; private set; } | ||||
| 		public IWindow Window { get { return window; } } | ||||
| 
 | ||||
|  | @ -41,11 +40,13 @@ namespace SafeExamBrowser.Browser | |||
| 		public BrowserApplicationInstance( | ||||
| 			AppConfig appConfig, | ||||
| 			BrowserSettings settings, | ||||
| 			InstanceIdentifier id, | ||||
| 			bool isMainInstance, | ||||
| 			IText text, | ||||
| 			IUserInterfaceFactory uiFactory, | ||||
| 			bool isMainInstance) | ||||
| 			IUserInterfaceFactory uiFactory) | ||||
| 		{ | ||||
| 			this.appConfig = appConfig; | ||||
| 			this.Id = id; | ||||
| 			this.isMainInstance = isMainInstance; | ||||
| 			this.settings = settings; | ||||
| 			this.text = text; | ||||
|  | @ -56,7 +57,6 @@ namespace SafeExamBrowser.Browser | |||
| 		{ | ||||
| 			var downloadHandler = new DownloadHandler(appConfig, settings); | ||||
| 
 | ||||
| 			Id = Guid.NewGuid(); | ||||
| 			downloadHandler.ConfigurationDownloadRequested += (fileName, args) => ConfigurationDownloadRequested?.Invoke(fileName, args); | ||||
| 
 | ||||
| 			control = new BrowserControl(appConfig, settings, text); | ||||
|  |  | |||
							
								
								
									
										42
									
								
								SafeExamBrowser.Browser/BrowserInstanceIdentifier.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								SafeExamBrowser.Browser/BrowserInstanceIdentifier.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 SafeExamBrowser.Contracts.Behaviour; | ||||
| 
 | ||||
| namespace SafeExamBrowser.Browser | ||||
| { | ||||
| 	internal class BrowserInstanceIdentifier : InstanceIdentifier | ||||
| 	{ | ||||
| 		public int Value { get; private set; } | ||||
| 
 | ||||
| 		public BrowserInstanceIdentifier(int id) | ||||
| 		{ | ||||
| 			Value = id; | ||||
| 		} | ||||
| 
 | ||||
| 		public override bool Equals(object other) | ||||
| 		{ | ||||
| 			if (other is BrowserInstanceIdentifier id) | ||||
| 			{ | ||||
| 				return Value == id.Value; | ||||
| 			} | ||||
| 
 | ||||
| 			return false; | ||||
| 		} | ||||
| 
 | ||||
| 		public override int GetHashCode() | ||||
| 		{ | ||||
| 			return Value.GetHashCode(); | ||||
| 		} | ||||
| 
 | ||||
| 		public override string ToString() | ||||
| 		{ | ||||
| 			return $"#{Value}"; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | @ -65,6 +65,7 @@ | |||
|     <Compile Include="BrowserApplicationController.cs" /> | ||||
|     <Compile Include="BrowserApplicationInfo.cs" /> | ||||
|     <Compile Include="BrowserApplicationInstance.cs" /> | ||||
|     <Compile Include="BrowserInstanceIdentifier.cs" /> | ||||
|     <Compile Include="Handlers\ContextMenuHandler.cs" /> | ||||
|     <Compile Include="BrowserControl.cs"> | ||||
|       <SubType>Component</SubType> | ||||
|  |  | |||
|  | @ -155,7 +155,7 @@ namespace SafeExamBrowser.Client | |||
| 
 | ||||
| 		private IOperation BuildBrowserOperation() | ||||
| 		{ | ||||
| 			var moduleLogger = new ModuleLogger(logger, typeof(BrowserApplicationController)); | ||||
| 			var moduleLogger = new ModuleLogger(logger, "BrowserController"); | ||||
| 			var browserController = new BrowserApplicationController(configuration.AppConfig, configuration.Settings.Browser, moduleLogger, messageBox, text, uiFactory); | ||||
| 			var browserInfo = new BrowserApplicationInfo(); | ||||
| 			var operation = new BrowserOperation(browserController, browserInfo, logger, Taskbar, uiFactory); | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ using System.IO; | |||
| using System.Reflection; | ||||
| using SafeExamBrowser.Contracts.Configuration; | ||||
| using SafeExamBrowser.Contracts.Configuration.Settings; | ||||
| using SafeExamBrowser.Contracts.Logging; | ||||
| 
 | ||||
| namespace SafeExamBrowser.Configuration | ||||
| { | ||||
|  | @ -81,7 +82,7 @@ namespace SafeExamBrowser.Configuration | |||
| 
 | ||||
| 			CurrentSettings = new Settings(); | ||||
| 
 | ||||
| 			CurrentSettings.KioskMode = KioskMode.DisableExplorerShell; | ||||
| 			CurrentSettings.KioskMode = KioskMode.None; | ||||
| 			CurrentSettings.ServicePolicy = ServicePolicy.Optional; | ||||
| 
 | ||||
| 			CurrentSettings.Browser.StartUrl = "https://www.safeexambrowser.org/testing"; | ||||
|  | @ -117,6 +118,7 @@ namespace SafeExamBrowser.Configuration | |||
| 			appConfig.ConfigurationFileExtension = ".seb"; | ||||
| 			appConfig.DefaultSettingsFileName = "SebClientSettings.seb"; | ||||
| 			appConfig.DownloadDirectory = Path.Combine(appDataFolder, "Downloads"); | ||||
| 			appConfig.LogLevel = LogLevel.Debug; | ||||
| 			appConfig.ProgramCopyright = executable.GetCustomAttribute<AssemblyCopyrightAttribute>().Copyright; | ||||
| 			appConfig.ProgramDataFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), nameof(SafeExamBrowser)); | ||||
| 			appConfig.ProgramTitle = executable.GetCustomAttribute<AssemblyTitleAttribute>().Title; | ||||
|  |  | |||
|  | @ -6,12 +6,11 @@ | |||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  */ | ||||
| 
 | ||||
| using System; | ||||
| 
 | ||||
| namespace SafeExamBrowser.Contracts.Behaviour.Events | ||||
| { | ||||
| 	/// <summary> | ||||
| 	/// Event handler used to indicate that an application instance with a particular ID has terminated. | ||||
| 	/// </summary> | ||||
| 	public delegate void InstanceTerminatedEventHandler(Guid id); | ||||
| 	public delegate void InstanceTerminatedEventHandler(InstanceIdentifier id); | ||||
| } | ||||
|  |  | |||
|  | @ -6,7 +6,6 @@ | |||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  */ | ||||
| 
 | ||||
| using System; | ||||
| using SafeExamBrowser.Contracts.Behaviour.Events; | ||||
| using SafeExamBrowser.Contracts.UserInterface.Windows; | ||||
| 
 | ||||
|  | @ -20,7 +19,7 @@ namespace SafeExamBrowser.Contracts.Behaviour | |||
| 		/// <summary> | ||||
| 		/// The unique identifier for the application instance. | ||||
| 		/// </summary> | ||||
| 		Guid Id { get; } | ||||
| 		InstanceIdentifier Id { get; } | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// The name or (document) title of the application instance. | ||||
|  |  | |||
							
								
								
									
										41
									
								
								SafeExamBrowser.Contracts/Behaviour/InstanceIdentifier.cs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								SafeExamBrowser.Contracts/Behaviour/InstanceIdentifier.cs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,41 @@ | |||
| /* | ||||
|  * 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.Behaviour | ||||
| { | ||||
| 	/// <summary> | ||||
| 	/// Defines an identifier which uniquely identifies an <see cref="IApplicationInstance"/> in the context of a (third-party) application. | ||||
| 	/// </summary> | ||||
| 	public abstract class InstanceIdentifier | ||||
| 	{ | ||||
| 		/// <summary> | ||||
| 		/// Determines whether two identifiers are equal (i.e. whether they identify the same <see cref="IApplicationInstance"/>). | ||||
| 		/// </summary> | ||||
| 		public static bool operator ==(InstanceIdentifier a, InstanceIdentifier b) => Equals(a, b); | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// Determines whether two identifiers are different (i.e. whether they identify different <see cref="IApplicationInstance"/>s). | ||||
| 		/// </summary> | ||||
| 		public static bool operator !=(InstanceIdentifier a, InstanceIdentifier b) => !Equals(a, b); | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// Indicates whether the given object is an <see cref="InstanceIdentifier"/> for the same <see cref="IApplicationInstance"/>. | ||||
| 		/// </summary> | ||||
| 		public abstract override bool Equals(object other); | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// Returns a hash code for the identifier. | ||||
| 		/// </summary> | ||||
| 		public abstract override int GetHashCode(); | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// Returns a human-readable string representation of the identifier. | ||||
| 		/// </summary> | ||||
| 		public abstract override string ToString(); | ||||
| 	} | ||||
| } | ||||
|  | @ -7,6 +7,7 @@ | |||
|  */ | ||||
| 
 | ||||
| using System; | ||||
| using SafeExamBrowser.Contracts.Logging; | ||||
| 
 | ||||
| namespace SafeExamBrowser.Contracts.Configuration | ||||
| { | ||||
|  | @ -71,6 +72,11 @@ namespace SafeExamBrowser.Contracts.Configuration | |||
| 		/// </summary> | ||||
| 		public string DownloadDirectory { get; set; } | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// The currently active, global log severity threshold. | ||||
| 		/// </summary> | ||||
| 		public LogLevel LogLevel { get; set; } | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// The copyright information for the application (i.e. the executing assembly). | ||||
| 		/// </summary> | ||||
|  |  | |||
|  | @ -17,32 +17,32 @@ namespace SafeExamBrowser.Contracts.Logging | |||
| 	public interface ILogger | ||||
| 	{ | ||||
| 		/// <summary> | ||||
| 		/// Logs the given message with severity <b>DEBUG</b>. | ||||
| 		/// Logs the given message with severity <see cref="LogLevel.Debug"/>. | ||||
| 		/// </summary> | ||||
| 		/// <exception cref="ArgumentNullException" /> | ||||
| 		void Debug(string message); | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// Logs the given message with severity <b>INFO</b>. | ||||
| 		/// Logs the given message with severity <see cref="LogLevel.Info"/>. | ||||
| 		/// </summary> | ||||
| 		/// <exception cref="ArgumentNullException" /> | ||||
| 		void Info(string message); | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// Logs the given message with severity <b>WARNING</b>. | ||||
| 		/// Logs the given message with severity <see cref="LogLevel.Warning"/>. | ||||
| 		/// </summary> | ||||
| 		/// <exception cref="ArgumentNullException" /> | ||||
| 		void Warn(string message); | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// Logs the given message with severity <b>ERROR</b>. | ||||
| 		/// Logs the given message with severity <see cref="LogLevel.Error"/>. | ||||
| 		/// </summary> | ||||
| 		/// <exception cref="ArgumentNullException" /> | ||||
| 		void Error(string message); | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// Logs the given message with severity <b>ERROR</b> and includes information about | ||||
| 		/// the specified exception (i.e. type, message and stacktrace). | ||||
| 		/// Logs the given message with severity <see cref="LogLevel.Error"/> and includes | ||||
| 		/// information about the specified exception (i.e. type, message and stacktrace). | ||||
| 		/// </summary> | ||||
| 		/// <exception cref="ArgumentNullException" /> | ||||
| 		void Error(string message, Exception exception); | ||||
|  | @ -60,7 +60,7 @@ namespace SafeExamBrowser.Contracts.Logging | |||
| 		void Log(ILogContent content); | ||||
| 
 | ||||
| 		/// <summary> | ||||
| 		/// Suscribes an observer to the application log. | ||||
| 		/// Subscribes an observer to the application log. | ||||
| 		/// </summary> | ||||
| 		/// <exception cref="ArgumentNullException" /> | ||||
| 		void Subscribe(ILogObserver observer); | ||||
|  |  | |||
|  | @ -55,6 +55,7 @@ | |||
|     <Compile Include="Behaviour\Events\InstanceTerminatedEventHandler.cs" /> | ||||
|     <Compile Include="Behaviour\Events\NameChangedEventHandler.cs" /> | ||||
|     <Compile Include="Behaviour\IApplicationController.cs" /> | ||||
|     <Compile Include="Behaviour\InstanceIdentifier.cs" /> | ||||
|     <Compile Include="Behaviour\IRuntimeController.cs" /> | ||||
|     <Compile Include="Behaviour\OperationModel\IOperationSequence.cs" /> | ||||
|     <Compile Include="Behaviour\OperationModel\OperationResult.cs" /> | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ | |||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  */ | ||||
| 
 | ||||
| using System; | ||||
| using SafeExamBrowser.Contracts.Behaviour; | ||||
| 
 | ||||
| namespace SafeExamBrowser.Contracts.UserInterface.Taskbar.Events | ||||
| { | ||||
|  | @ -14,5 +14,5 @@ namespace SafeExamBrowser.Contracts.UserInterface.Taskbar.Events | |||
| 	/// Indicates that an <see cref="IApplicationButton"/> has been clicked, optionally specifying the ID of the selected instance (if | ||||
| 	/// multiple instances of the same application are running). | ||||
| 	/// </summary> | ||||
| 	public delegate void ApplicationButtonClickedEventHandler(Guid? instanceId = null); | ||||
| 	public delegate void ApplicationButtonClickedEventHandler(InstanceIdentifier id = null); | ||||
| } | ||||
|  |  | |||
|  | @ -8,6 +8,9 @@ | |||
| 
 | ||||
| namespace SafeExamBrowser.Contracts.WindowsApi | ||||
| { | ||||
| 	/// <summary> | ||||
| 	/// Defines an abstraction of the Windows explorer shell (i.e. the process controlling the GUI of the operating system). | ||||
| 	/// </summary> | ||||
| 	public interface IExplorerShell | ||||
| 	{ | ||||
| 		/// <summary> | ||||
|  |  | |||
|  | @ -23,7 +23,7 @@ namespace SafeExamBrowser.Core.Communication.Proxies | |||
| 	public abstract class BaseProxy : ICommunicationProxy | ||||
| 	{ | ||||
| 		private const int ONE_MINUTE = 60000; | ||||
| 		private static readonly object @lock = new object(); | ||||
| 		private readonly object @lock = new object(); | ||||
| 
 | ||||
| 		private string address; | ||||
| 		private IProxyObject proxy; | ||||
|  |  | |||
|  | @ -17,7 +17,7 @@ namespace SafeExamBrowser.Core.Logging | |||
| 	/// </summary> | ||||
| 	public class LogFileWriter : ILogObserver | ||||
| 	{ | ||||
| 		private static readonly object @lock = new object(); | ||||
| 		private readonly object @lock = new object(); | ||||
| 		private readonly string filePath; | ||||
| 		private readonly ILogContentFormatter formatter; | ||||
| 
 | ||||
|  |  | |||
|  | @ -20,7 +20,7 @@ namespace SafeExamBrowser.Core.Logging | |||
| 	/// </summary> | ||||
| 	public class Logger : ILogger | ||||
| 	{ | ||||
| 		private static readonly object @lock = new object(); | ||||
| 		private readonly object @lock = new object(); | ||||
| 		private readonly IList<ILogContent> log = new List<ILogContent>(); | ||||
| 		private readonly IList<ILogObserver> observers = new List<ILogObserver>(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -18,12 +18,16 @@ namespace SafeExamBrowser.Core.Logging | |||
| 	public class ModuleLogger : ILogger | ||||
| 	{ | ||||
| 		private ILogger logger; | ||||
| 		private Type module; | ||||
| 		private string moduleInfo; | ||||
| 
 | ||||
| 		public ModuleLogger(ILogger logger, Type module) | ||||
| 		public ModuleLogger(ILogger logger, string moduleInfo) | ||||
| 		{ | ||||
| 			this.logger = logger; | ||||
| 			this.module = module; | ||||
| 			this.moduleInfo = moduleInfo; | ||||
| 		} | ||||
| 
 | ||||
| 		public ModuleLogger(ILogger logger, Type module) : this(logger, module.Name) | ||||
| 		{ | ||||
| 		} | ||||
| 
 | ||||
| 		public void Debug(string message) | ||||
|  | @ -78,7 +82,7 @@ namespace SafeExamBrowser.Core.Logging | |||
| 
 | ||||
| 		private string AppendModuleInfo(string message) | ||||
| 		{ | ||||
| 			return $"[{module.Name}] {message}"; | ||||
| 			return $"[{moduleInfo}] {message}"; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -6,7 +6,6 @@ | |||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  */ | ||||
| 
 | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Windows; | ||||
|  | @ -90,7 +89,7 @@ namespace SafeExamBrowser.UserInterface.Classic.Controls | |||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		private void Instance_OnTerminated(Guid id, ApplicationInstanceButton instanceButton) | ||||
| 		private void Instance_OnTerminated(InstanceIdentifier id, ApplicationInstanceButton instanceButton) | ||||
| 		{ | ||||
| 			instances.Remove(instances.FirstOrDefault(i => i.Id == id)); | ||||
| 			InstanceStackPanel.Children.Remove(instanceButton); | ||||
|  |  | |||
|  | @ -6,23 +6,21 @@ | |||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  */ | ||||
| 
 | ||||
| using System; | ||||
| using System.Windows; | ||||
| using System.Windows.Controls; | ||||
| using SafeExamBrowser.Contracts.Behaviour; | ||||
| using SafeExamBrowser.Contracts.Configuration; | ||||
| using SafeExamBrowser.Contracts.UserInterface.Taskbar.Events; | ||||
| using SafeExamBrowser.UserInterface.Classic.Utilities; | ||||
| 
 | ||||
| namespace SafeExamBrowser.UserInterface.Classic.Controls | ||||
| { | ||||
| 	internal delegate void InstanceButtonClickedEventHandler(Guid instanceId); | ||||
| 
 | ||||
| 	public partial class ApplicationInstanceButton : UserControl | ||||
| 	{ | ||||
| 		private IApplicationInfo info; | ||||
| 		private IApplicationInstance instance; | ||||
| 
 | ||||
| 		internal event InstanceButtonClickedEventHandler Clicked; | ||||
| 		internal event ApplicationButtonClickedEventHandler Clicked; | ||||
| 
 | ||||
| 		public ApplicationInstanceButton(IApplicationInstance instance, IApplicationInfo info) | ||||
| 		{ | ||||
|  |  | |||
|  | @ -91,7 +91,7 @@ namespace SafeExamBrowser.UserInterface.Windows10.Controls | |||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		private void Instance_OnTerminated(Guid id, ApplicationInstanceButton instanceButton) | ||||
| 		private void Instance_OnTerminated(InstanceIdentifier id, ApplicationInstanceButton instanceButton) | ||||
| 		{ | ||||
| 			instances.Remove(instances.FirstOrDefault(i => i.Id == id)); | ||||
| 			InstanceStackPanel.Children.Remove(instanceButton); | ||||
|  |  | |||
|  | @ -6,23 +6,21 @@ | |||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||||
|  */ | ||||
| 
 | ||||
| using System; | ||||
| using System.Windows; | ||||
| using System.Windows.Controls; | ||||
| using SafeExamBrowser.Contracts.Behaviour; | ||||
| using SafeExamBrowser.Contracts.Configuration; | ||||
| using SafeExamBrowser.Contracts.UserInterface.Taskbar.Events; | ||||
| using SafeExamBrowser.UserInterface.Windows10.Utilities; | ||||
| 
 | ||||
| namespace SafeExamBrowser.UserInterface.Windows10.Controls | ||||
| { | ||||
| 	internal delegate void InstanceButtonClickedEventHandler(Guid instanceId); | ||||
| 
 | ||||
| 	public partial class ApplicationInstanceButton : UserControl | ||||
| 	{ | ||||
| 		private IApplicationInfo info; | ||||
| 		private IApplicationInstance instance; | ||||
| 
 | ||||
| 		internal event InstanceButtonClickedEventHandler Clicked; | ||||
| 		internal event ApplicationButtonClickedEventHandler Clicked; | ||||
| 
 | ||||
| 		public ApplicationInstanceButton(IApplicationInstance instance, IApplicationInfo info) | ||||
| 		{ | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 dbuechel
						dbuechel