SEBWIN-219: Found better solution for session operation sequence (got rid of session controller and sequence start resp. end operations).
This commit is contained in:
parent
e750f870c0
commit
6efa7bed81
15 changed files with 270 additions and 246 deletions
|
@ -43,14 +43,14 @@ namespace SafeExamBrowser.Contracts.I18n
|
||||||
Notification_AboutTooltip,
|
Notification_AboutTooltip,
|
||||||
Notification_LogTooltip,
|
Notification_LogTooltip,
|
||||||
ProgressIndicator_CloseRuntimeConnection,
|
ProgressIndicator_CloseRuntimeConnection,
|
||||||
ProgressIndicator_CloseServiceConnection,
|
|
||||||
ProgressIndicator_EmptyClipboard,
|
ProgressIndicator_EmptyClipboard,
|
||||||
|
ProgressIndicator_FinalizeServiceSession,
|
||||||
ProgressIndicator_InitializeBrowser,
|
ProgressIndicator_InitializeBrowser,
|
||||||
ProgressIndicator_InitializeConfiguration,
|
ProgressIndicator_InitializeConfiguration,
|
||||||
ProgressIndicator_InitializeKioskMode,
|
ProgressIndicator_InitializeKioskMode,
|
||||||
ProgressIndicator_InitializeProcessMonitoring,
|
ProgressIndicator_InitializeProcessMonitoring,
|
||||||
ProgressIndicator_InitializeRuntimeConnection,
|
ProgressIndicator_InitializeRuntimeConnection,
|
||||||
ProgressIndicator_InitializeServiceConnection,
|
ProgressIndicator_InitializeServiceSession,
|
||||||
ProgressIndicator_InitializeTaskbar,
|
ProgressIndicator_InitializeTaskbar,
|
||||||
ProgressIndicator_InitializeWindowMonitoring,
|
ProgressIndicator_InitializeWindowMonitoring,
|
||||||
ProgressIndicator_InitializeWorkingArea,
|
ProgressIndicator_InitializeWorkingArea,
|
||||||
|
@ -58,17 +58,18 @@ namespace SafeExamBrowser.Contracts.I18n
|
||||||
ProgressIndicator_RestoreWorkingArea,
|
ProgressIndicator_RestoreWorkingArea,
|
||||||
ProgressIndicator_RevertKioskMode,
|
ProgressIndicator_RevertKioskMode,
|
||||||
ProgressIndicator_ShutdownProcedure,
|
ProgressIndicator_ShutdownProcedure,
|
||||||
|
ProgressIndicator_StartClient,
|
||||||
ProgressIndicator_StartCommunicationHost,
|
ProgressIndicator_StartCommunicationHost,
|
||||||
ProgressIndicator_StartEventHandling,
|
ProgressIndicator_StartEventHandling,
|
||||||
ProgressIndicator_StartKeyboardInterception,
|
ProgressIndicator_StartKeyboardInterception,
|
||||||
ProgressIndicator_StartMouseInterception,
|
ProgressIndicator_StartMouseInterception,
|
||||||
ProgressIndicator_StartSession,
|
ProgressIndicator_InitializeSession,
|
||||||
|
ProgressIndicator_StopClient,
|
||||||
ProgressIndicator_StopCommunicationHost,
|
ProgressIndicator_StopCommunicationHost,
|
||||||
ProgressIndicator_StopEventHandling,
|
ProgressIndicator_StopEventHandling,
|
||||||
ProgressIndicator_StopKeyboardInterception,
|
ProgressIndicator_StopKeyboardInterception,
|
||||||
ProgressIndicator_StopMouseInterception,
|
ProgressIndicator_StopMouseInterception,
|
||||||
ProgressIndicator_StopProcessMonitoring,
|
ProgressIndicator_StopProcessMonitoring,
|
||||||
ProgressIndicator_StopSession,
|
|
||||||
ProgressIndicator_StopWindowMonitoring,
|
ProgressIndicator_StopWindowMonitoring,
|
||||||
ProgressIndicator_TerminateBrowser,
|
ProgressIndicator_TerminateBrowser,
|
||||||
ProgressIndicator_TerminateTaskbar,
|
ProgressIndicator_TerminateTaskbar,
|
||||||
|
|
|
@ -81,12 +81,12 @@
|
||||||
<Entry key="ProgressIndicator_CloseRuntimeConnection">
|
<Entry key="ProgressIndicator_CloseRuntimeConnection">
|
||||||
Closing runtime connection
|
Closing runtime connection
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="ProgressIndicator_CloseServiceConnection">
|
|
||||||
Closing service connection
|
|
||||||
</Entry>
|
|
||||||
<Entry key="ProgressIndicator_EmptyClipboard">
|
<Entry key="ProgressIndicator_EmptyClipboard">
|
||||||
Emptying clipboard
|
Emptying clipboard
|
||||||
</Entry>
|
</Entry>
|
||||||
|
<Entry key="ProgressIndicator_FinalizeServiceSession">
|
||||||
|
Finalizing service session
|
||||||
|
</Entry>
|
||||||
<Entry key="ProgressIndicator_InitializeBrowser">
|
<Entry key="ProgressIndicator_InitializeBrowser">
|
||||||
Initializing browser
|
Initializing browser
|
||||||
</Entry>
|
</Entry>
|
||||||
|
@ -102,8 +102,11 @@
|
||||||
<Entry key="ProgressIndicator_InitializeRuntimeConnection">
|
<Entry key="ProgressIndicator_InitializeRuntimeConnection">
|
||||||
Initializing runtime connection
|
Initializing runtime connection
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="ProgressIndicator_InitializeServiceConnection">
|
<Entry key="ProgressIndicator_InitializeServiceSession">
|
||||||
Initializing service connection
|
Initializing service session
|
||||||
|
</Entry>
|
||||||
|
<Entry key="ProgressIndicator_InitializeSession">
|
||||||
|
Initializing new session
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="ProgressIndicator_InitializeTaskbar">
|
<Entry key="ProgressIndicator_InitializeTaskbar">
|
||||||
Initializing taskbar
|
Initializing taskbar
|
||||||
|
@ -126,6 +129,9 @@
|
||||||
<Entry key="ProgressIndicator_ShutdownProcedure">
|
<Entry key="ProgressIndicator_ShutdownProcedure">
|
||||||
Initiating shutdown procedure
|
Initiating shutdown procedure
|
||||||
</Entry>
|
</Entry>
|
||||||
|
<Entry key="ProgressIndicator_StartClient">
|
||||||
|
Starting client
|
||||||
|
</Entry>
|
||||||
<Entry key="ProgressIndicator_StartCommunicationHost">
|
<Entry key="ProgressIndicator_StartCommunicationHost">
|
||||||
Starting communication host
|
Starting communication host
|
||||||
</Entry>
|
</Entry>
|
||||||
|
@ -138,8 +144,8 @@
|
||||||
<Entry key="ProgressIndicator_StartMouseInterception">
|
<Entry key="ProgressIndicator_StartMouseInterception">
|
||||||
Starting mouse interception
|
Starting mouse interception
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="ProgressIndicator_StartSession">
|
<Entry key="ProgressIndicator_StopClient">
|
||||||
Starting new session
|
Stopping client
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="ProgressIndicator_StopCommunicationHost">
|
<Entry key="ProgressIndicator_StopCommunicationHost">
|
||||||
Stopping communication host
|
Stopping communication host
|
||||||
|
@ -156,9 +162,6 @@
|
||||||
<Entry key="ProgressIndicator_StopProcessMonitoring">
|
<Entry key="ProgressIndicator_StopProcessMonitoring">
|
||||||
Stopping process monitoring
|
Stopping process monitoring
|
||||||
</Entry>
|
</Entry>
|
||||||
<Entry key="ProgressIndicator_StopSession">
|
|
||||||
Stopping current session
|
|
||||||
</Entry>
|
|
||||||
<Entry key="ProgressIndicator_StopWindowMonitoring">
|
<Entry key="ProgressIndicator_StopWindowMonitoring">
|
||||||
Stopping window monitoring
|
Stopping window monitoring
|
||||||
</Entry>
|
</Entry>
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
||||||
private Mock<IConfigurationRepository> configuration;
|
private Mock<IConfigurationRepository> configuration;
|
||||||
private Mock<IProgressIndicator> progressIndicator;
|
private Mock<IProgressIndicator> progressIndicator;
|
||||||
private Mock<IText> text;
|
private Mock<IText> text;
|
||||||
private ServiceConnectionOperation sut;
|
private ServiceOperation sut;
|
||||||
|
|
||||||
[TestInitialize]
|
[TestInitialize]
|
||||||
public void Initialize()
|
public void Initialize()
|
||||||
|
@ -39,7 +39,7 @@ namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
||||||
progressIndicator = new Mock<IProgressIndicator>();
|
progressIndicator = new Mock<IProgressIndicator>();
|
||||||
text = new Mock<IText>();
|
text = new Mock<IText>();
|
||||||
|
|
||||||
sut = new ServiceConnectionOperation(configuration.Object, logger.Object, service.Object, text.Object);
|
sut = new ServiceOperation(configuration.Object, logger.Object, service.Object, text.Object);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestMethod]
|
[TestMethod]
|
||||||
|
|
|
@ -1,22 +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 Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.Runtime.UnitTests.Behaviour.Operations
|
|
||||||
{
|
|
||||||
[TestClass]
|
|
||||||
public class SessionSequenceOperationTests
|
|
||||||
{
|
|
||||||
[TestMethod]
|
|
||||||
public void TODO()
|
|
||||||
{
|
|
||||||
Assert.Fail();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -83,7 +83,6 @@
|
||||||
<Compile Include="Behaviour\Operations\ConfigurationOperationTests.cs" />
|
<Compile Include="Behaviour\Operations\ConfigurationOperationTests.cs" />
|
||||||
<Compile Include="Behaviour\Operations\KioskModeOperationTests.cs" />
|
<Compile Include="Behaviour\Operations\KioskModeOperationTests.cs" />
|
||||||
<Compile Include="Behaviour\Operations\ServiceConnectionOperationTests.cs" />
|
<Compile Include="Behaviour\Operations\ServiceConnectionOperationTests.cs" />
|
||||||
<Compile Include="Behaviour\Operations\SessionSequenceOperationTests.cs" />
|
|
||||||
<Compile Include="Behaviour\RuntimeControllerTests.cs" />
|
<Compile Include="Behaviour\RuntimeControllerTests.cs" />
|
||||||
<Compile Include="Communication\RuntimeHostTests.cs" />
|
<Compile Include="Communication\RuntimeHostTests.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
|
|
@ -17,104 +17,69 @@ using SafeExamBrowser.Contracts.Logging;
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
using SafeExamBrowser.Contracts.UserInterface;
|
||||||
using SafeExamBrowser.Contracts.WindowsApi;
|
using SafeExamBrowser.Contracts.WindowsApi;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Runtime.Behaviour
|
namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
{
|
{
|
||||||
internal class SessionController
|
internal class ClientOperation : IOperation
|
||||||
{
|
{
|
||||||
private const int TEN_SECONDS = 10000;
|
private const int TEN_SECONDS = 10000;
|
||||||
|
|
||||||
private bool sessionRunning;
|
protected IConfigurationRepository configuration;
|
||||||
private IConfigurationRepository configuration;
|
protected ILogger logger;
|
||||||
private ILogger logger;
|
protected IProcessFactory processFactory;
|
||||||
private IProcessFactory processFactory;
|
protected IProxyFactory proxyFactory;
|
||||||
private IProxyFactory proxyFactory;
|
protected IRuntimeHost runtimeHost;
|
||||||
private IRuntimeHost runtimeHost;
|
|
||||||
private IServiceProxy service;
|
|
||||||
|
|
||||||
internal IProgressIndicator ProgressIndicator { private get; set; }
|
protected static IProcess ClientProcess { get; private set; }
|
||||||
|
protected static IClientProxy ClientProxy { get; private set; }
|
||||||
|
public IProgressIndicator ProgressIndicator { protected get; set; }
|
||||||
|
|
||||||
internal SessionController(
|
public ClientOperation(
|
||||||
IConfigurationRepository configuration,
|
IConfigurationRepository configuration,
|
||||||
ILogger logger,
|
ILogger logger,
|
||||||
IProcessFactory processFactory,
|
IProcessFactory processFactory,
|
||||||
IProxyFactory proxyFactory,
|
IProxyFactory proxyFactory,
|
||||||
IRuntimeHost runtimeHost,
|
IRuntimeHost runtimeHost)
|
||||||
IServiceProxy service)
|
|
||||||
{
|
{
|
||||||
this.configuration = configuration;
|
this.configuration = configuration;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
this.processFactory = processFactory;
|
this.processFactory = processFactory;
|
||||||
this.proxyFactory = proxyFactory;
|
this.proxyFactory = proxyFactory;
|
||||||
this.runtimeHost = runtimeHost;
|
this.runtimeHost = runtimeHost;
|
||||||
this.service = service;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal OperationResult StartSession()
|
public virtual OperationResult Perform()
|
||||||
{
|
{
|
||||||
logger.Info("Starting new session...");
|
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StartClient, true);
|
||||||
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StartSession, true);
|
|
||||||
|
|
||||||
InitializeSessionConfiguration();
|
var success = TryStartClient();
|
||||||
StartServiceSession();
|
|
||||||
sessionRunning = TryStartClient();
|
|
||||||
|
|
||||||
if (!sessionRunning)
|
if (success)
|
||||||
{
|
{
|
||||||
logger.Info($"Failed to start new session! Reverting service session and aborting procedure...");
|
logger.Info($"Successfully started new client instance.");
|
||||||
service.StopSession(configuration.CurrentSession.Id);
|
}
|
||||||
|
else
|
||||||
return OperationResult.Failed;
|
{
|
||||||
|
logger.Error($"Failed to start new client instance! Aborting procedure...");
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info($"Successfully started new session.");
|
return success ? OperationResult.Success : OperationResult.Failed;
|
||||||
|
|
||||||
return OperationResult.Success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal OperationResult StopSession()
|
public virtual OperationResult Repeat()
|
||||||
{
|
{
|
||||||
if (sessionRunning)
|
return Perform();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Revert()
|
||||||
|
{
|
||||||
|
if (ClientProcess != null && !ClientProcess.HasTerminated)
|
||||||
{
|
{
|
||||||
logger.Info($"Stopping session with identifier '{configuration.CurrentSession.Id}'...");
|
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StopClient, true);
|
||||||
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StopSession, true);
|
TryStopClient();
|
||||||
|
|
||||||
StopServiceSession();
|
|
||||||
|
|
||||||
if (!configuration.CurrentSession.ClientProcess.HasTerminated)
|
|
||||||
{
|
|
||||||
StopClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
sessionRunning = false;
|
|
||||||
logger.Info($"Successfully stopped session.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return OperationResult.Success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeSessionConfiguration()
|
protected bool TryStartClient()
|
||||||
{
|
|
||||||
configuration.InitializeSessionConfiguration();
|
|
||||||
runtimeHost.StartupToken = configuration.CurrentSession.StartupToken;
|
|
||||||
|
|
||||||
logger.Info($" -> Client-ID: {configuration.RuntimeInfo.ClientId}");
|
|
||||||
logger.Info($" -> Runtime-ID: {configuration.RuntimeInfo.RuntimeId} (as reference, does not change)");
|
|
||||||
logger.Info($" -> Session-ID: {configuration.CurrentSession.Id}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void StartServiceSession()
|
|
||||||
{
|
|
||||||
logger.Info("Initializing service session...");
|
|
||||||
service.StartSession(configuration.CurrentSession.Id, configuration.CurrentSettings);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void StopServiceSession()
|
|
||||||
{
|
|
||||||
logger.Info("Stopping service session...");
|
|
||||||
service.StopSession(configuration.CurrentSession.Id);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool TryStartClient()
|
|
||||||
{
|
{
|
||||||
var clientReady = false;
|
var clientReady = false;
|
||||||
var clientReadyEvent = new AutoResetEvent(false);
|
var clientReadyEvent = new AutoResetEvent(false);
|
||||||
|
@ -126,7 +91,7 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
||||||
|
|
||||||
logger.Info("Starting new client process...");
|
logger.Info("Starting new client process...");
|
||||||
runtimeHost.ClientReady += clientReadyEventHandler;
|
runtimeHost.ClientReady += clientReadyEventHandler;
|
||||||
configuration.CurrentSession.ClientProcess = processFactory.StartNew(clientExecutable, clientLogFile, hostUri, token);
|
ClientProcess = processFactory.StartNew(clientExecutable, clientLogFile, hostUri, token);
|
||||||
|
|
||||||
logger.Info("Waiting for client to complete initialization...");
|
logger.Info("Waiting for client to complete initialization...");
|
||||||
clientReady = clientReadyEvent.WaitOne(TEN_SECONDS);
|
clientReady = clientReadyEvent.WaitOne(TEN_SECONDS);
|
||||||
|
@ -140,20 +105,20 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info("Client has been successfully started and initialized. Creating communication proxy for client host...");
|
logger.Info("Client has been successfully started and initialized. Creating communication proxy for client host...");
|
||||||
configuration.CurrentSession.ClientProxy = proxyFactory.CreateClientProxy(configuration.RuntimeInfo.ClientAddress);
|
ClientProxy = proxyFactory.CreateClientProxy(configuration.RuntimeInfo.ClientAddress);
|
||||||
|
|
||||||
if (!configuration.CurrentSession.ClientProxy.Connect(configuration.CurrentSession.StartupToken))
|
if (!ClientProxy.Connect(configuration.CurrentSession.StartupToken))
|
||||||
{
|
{
|
||||||
logger.Error("Failed to connect to client!");
|
logger.Error("Failed to connect to client!");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info("Connection with client has been established.");
|
logger.Info("Connection with client has been established. Requesting authentication...");
|
||||||
|
|
||||||
var response = configuration.CurrentSession.ClientProxy.RequestAuthentication();
|
var response = ClientProxy.RequestAuthentication();
|
||||||
|
|
||||||
if (configuration.CurrentSession.ClientProcess.Id != response?.ProcessId)
|
if (ClientProcess.Id != response?.ProcessId)
|
||||||
{
|
{
|
||||||
logger.Error("Failed to verify client integrity!");
|
logger.Error("Failed to verify client integrity!");
|
||||||
|
|
||||||
|
@ -162,11 +127,16 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
||||||
|
|
||||||
logger.Info("Authentication of client has been successful, client is ready to operate.");
|
logger.Info("Authentication of client has been successful, client is ready to operate.");
|
||||||
|
|
||||||
|
configuration.CurrentSession.ClientProcess = ClientProcess;
|
||||||
|
configuration.CurrentSession.ClientProxy = ClientProxy;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StopClient()
|
protected bool TryStopClient()
|
||||||
{
|
{
|
||||||
|
var success = false;
|
||||||
|
|
||||||
var disconnected = false;
|
var disconnected = false;
|
||||||
var disconnectedEvent = new AutoResetEvent(false);
|
var disconnectedEvent = new AutoResetEvent(false);
|
||||||
var disconnectedEventHandler = new CommunicationEventHandler(() => disconnectedEvent.Set());
|
var disconnectedEventHandler = new CommunicationEventHandler(() => disconnectedEvent.Set());
|
||||||
|
@ -176,13 +146,13 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
||||||
var terminatedEventHandler = new ProcessTerminatedEventHandler((_) => terminatedEvent.Set());
|
var terminatedEventHandler = new ProcessTerminatedEventHandler((_) => terminatedEvent.Set());
|
||||||
|
|
||||||
runtimeHost.ClientDisconnected += disconnectedEventHandler;
|
runtimeHost.ClientDisconnected += disconnectedEventHandler;
|
||||||
configuration.CurrentSession.ClientProcess.Terminated += terminatedEventHandler;
|
ClientProcess.Terminated += terminatedEventHandler;
|
||||||
|
|
||||||
logger.Info("Instructing client to initiate shutdown procedure.");
|
logger.Info("Instructing client to initiate shutdown procedure.");
|
||||||
configuration.CurrentSession.ClientProxy.InitiateShutdown();
|
ClientProxy.InitiateShutdown();
|
||||||
|
|
||||||
logger.Info("Disconnecting from client communication host.");
|
logger.Info("Disconnecting from client communication host.");
|
||||||
configuration.CurrentSession.ClientProxy.Disconnect();
|
ClientProxy.Disconnect();
|
||||||
|
|
||||||
logger.Info("Waiting for client to disconnect from runtime communication host...");
|
logger.Info("Waiting for client to disconnect from runtime communication host...");
|
||||||
disconnected = disconnectedEvent.WaitOne(TEN_SECONDS);
|
disconnected = disconnectedEvent.WaitOne(TEN_SECONDS);
|
||||||
|
@ -201,20 +171,29 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
||||||
}
|
}
|
||||||
|
|
||||||
runtimeHost.ClientDisconnected -= disconnectedEventHandler;
|
runtimeHost.ClientDisconnected -= disconnectedEventHandler;
|
||||||
configuration.CurrentSession.ClientProcess.Terminated -= terminatedEventHandler;
|
ClientProcess.Terminated -= terminatedEventHandler;
|
||||||
|
|
||||||
if (disconnected && terminated)
|
if (disconnected && terminated)
|
||||||
{
|
{
|
||||||
logger.Info("Client has been successfully terminated.");
|
logger.Info("Client has been successfully terminated.");
|
||||||
|
success = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logger.Warn("Attempting to kill client process since graceful termination failed!");
|
logger.Warn("Attempting to kill client process since graceful termination failed!");
|
||||||
KillClient();
|
success = TryKillClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (success)
|
||||||
|
{
|
||||||
|
configuration.CurrentSession.ClientProcess = null;
|
||||||
|
configuration.CurrentSession.ClientProxy = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void KillClient(int attempt = 0)
|
protected bool TryKillClient(int attempt = 0)
|
||||||
{
|
{
|
||||||
const int MAX_ATTEMPTS = 5;
|
const int MAX_ATTEMPTS = 5;
|
||||||
|
|
||||||
|
@ -222,20 +201,23 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
||||||
{
|
{
|
||||||
logger.Error($"Failed to kill client process within {MAX_ATTEMPTS} attempts!");
|
logger.Error($"Failed to kill client process within {MAX_ATTEMPTS} attempts!");
|
||||||
|
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info($"Killing client process with ID = {configuration.CurrentSession.ClientProcess.Id}.");
|
logger.Info($"Killing client process with ID = {ClientProcess.Id}.");
|
||||||
configuration.CurrentSession.ClientProcess.Kill();
|
ClientProcess.Kill();
|
||||||
|
|
||||||
if (configuration.CurrentSession.ClientProcess.HasTerminated)
|
if (ClientProcess.HasTerminated)
|
||||||
{
|
{
|
||||||
logger.Info("Client process has terminated.");
|
logger.Info("Client process has terminated.");
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
logger.Warn("Failed to kill client process. Trying again...");
|
logger.Warn("Failed to kill client process. Trying again...");
|
||||||
KillClient(attempt++);
|
|
||||||
|
return TryKillClient(attempt++);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* 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.OperationModel;
|
||||||
|
using SafeExamBrowser.Contracts.Communication.Hosts;
|
||||||
|
using SafeExamBrowser.Contracts.Communication.Proxies;
|
||||||
|
using SafeExamBrowser.Contracts.Configuration;
|
||||||
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
|
using SafeExamBrowser.Contracts.WindowsApi;
|
||||||
|
|
||||||
|
namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
|
{
|
||||||
|
internal class ClientTerminationOperation : ClientOperation
|
||||||
|
{
|
||||||
|
public ClientTerminationOperation(
|
||||||
|
IConfigurationRepository configuration,
|
||||||
|
ILogger logger,
|
||||||
|
IProcessFactory processFactory,
|
||||||
|
IProxyFactory proxyFactory,
|
||||||
|
IRuntimeHost runtimeHost) : base(configuration, logger, processFactory, proxyFactory, runtimeHost)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override OperationResult Perform()
|
||||||
|
{
|
||||||
|
return OperationResult.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override OperationResult Repeat()
|
||||||
|
{
|
||||||
|
var success = true;
|
||||||
|
|
||||||
|
if (ClientProcess != null && !ClientProcess.HasTerminated)
|
||||||
|
{
|
||||||
|
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_StopClient, true);
|
||||||
|
success = TryStopClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
return success ? OperationResult.Success : OperationResult.Failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Revert()
|
||||||
|
{
|
||||||
|
// Nothing to do here...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,8 +23,8 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
private IConfigurationRepository repository;
|
private IConfigurationRepository repository;
|
||||||
private ILogger logger;
|
private ILogger logger;
|
||||||
private IMessageBox messageBox;
|
private IMessageBox messageBox;
|
||||||
private RuntimeInfo runtimeInfo;
|
|
||||||
private IText text;
|
private IText text;
|
||||||
|
private RuntimeInfo runtimeInfo;
|
||||||
private string[] commandLineArgs;
|
private string[] commandLineArgs;
|
||||||
|
|
||||||
public IProgressIndicator ProgressIndicator { private get; set; }
|
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||||
|
@ -50,30 +50,23 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
logger.Info("Initializing application configuration...");
|
logger.Info("Initializing application configuration...");
|
||||||
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeConfiguration);
|
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeConfiguration);
|
||||||
|
|
||||||
Settings settings;
|
|
||||||
var isValidUri = TryGetSettingsUri(out Uri uri);
|
var isValidUri = TryGetSettingsUri(out Uri uri);
|
||||||
|
|
||||||
if (isValidUri)
|
if (isValidUri)
|
||||||
{
|
{
|
||||||
logger.Info($"Loading configuration from '{uri.AbsolutePath}'...");
|
logger.Info($"Loading configuration from '{uri.AbsolutePath}'...");
|
||||||
settings = repository.LoadSettings(uri);
|
|
||||||
|
|
||||||
if (settings.ConfigurationMode == ConfigurationMode.ConfigureClient)
|
var abort = LoadSettings(uri);
|
||||||
|
|
||||||
|
if (abort)
|
||||||
{
|
{
|
||||||
var abort = IsConfigurationSufficient();
|
return OperationResult.Aborted;
|
||||||
|
|
||||||
logger.Info($"The user chose to {(abort ? "abort" : "continue")} after successful client configuration.");
|
|
||||||
|
|
||||||
if (abort)
|
|
||||||
{
|
|
||||||
return OperationResult.Aborted;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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.LoadDefaultSettings();
|
repository.LoadDefaultSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
return OperationResult.Success;
|
return OperationResult.Success;
|
||||||
|
@ -126,6 +119,21 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
return isValidUri;
|
return isValidUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool LoadSettings(Uri uri)
|
||||||
|
{
|
||||||
|
var abort = false;
|
||||||
|
var settings = repository.LoadSettings(uri);
|
||||||
|
|
||||||
|
if (settings.ConfigurationMode == ConfigurationMode.ConfigureClient)
|
||||||
|
{
|
||||||
|
abort = IsConfigurationSufficient();
|
||||||
|
|
||||||
|
logger.Info($"The user chose to {(abort ? "abort" : "continue")} after successful client configuration.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return abort;
|
||||||
|
}
|
||||||
|
|
||||||
private bool IsConfigurationSufficient()
|
private bool IsConfigurationSufficient()
|
||||||
{
|
{
|
||||||
var message = text.Get(TextKey.MessageBox_ClientConfigurationQuestion);
|
var message = text.Get(TextKey.MessageBox_ClientConfigurationQuestion);
|
||||||
|
|
|
@ -17,7 +17,7 @@ using SafeExamBrowser.Contracts.UserInterface;
|
||||||
|
|
||||||
namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
{
|
{
|
||||||
internal class ServiceConnectionOperation : IOperation
|
internal class ServiceOperation : IOperation
|
||||||
{
|
{
|
||||||
private bool connected, mandatory;
|
private bool connected, mandatory;
|
||||||
private IConfigurationRepository configuration;
|
private IConfigurationRepository configuration;
|
||||||
|
@ -27,7 +27,7 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
|
|
||||||
public IProgressIndicator ProgressIndicator { private get; set; }
|
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||||
|
|
||||||
public ServiceConnectionOperation(IConfigurationRepository configuration, ILogger logger, IServiceProxy service, IText text)
|
public ServiceOperation(IConfigurationRepository configuration, ILogger logger, IServiceProxy service, IText text)
|
||||||
{
|
{
|
||||||
this.configuration = configuration;
|
this.configuration = configuration;
|
||||||
this.service = service;
|
this.service = service;
|
||||||
|
@ -37,8 +37,8 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
|
|
||||||
public OperationResult Perform()
|
public OperationResult Perform()
|
||||||
{
|
{
|
||||||
logger.Info($"Initializing service connection...");
|
logger.Info($"Initializing service session...");
|
||||||
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeServiceConnection);
|
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeServiceSession);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -60,23 +60,35 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
service.Ignore = !connected;
|
service.Ignore = !connected;
|
||||||
logger.Info($"The service is {(mandatory ? "mandatory" : "optional")} and {(connected ? "available." : "not available. All service-related operations will be ignored!")}");
|
logger.Info($"The service is {(mandatory ? "mandatory" : "optional")} and {(connected ? "available." : "not available. All service-related operations will be ignored!")}");
|
||||||
|
|
||||||
|
if (connected)
|
||||||
|
{
|
||||||
|
StartServiceSession();
|
||||||
|
}
|
||||||
|
|
||||||
return OperationResult.Success;
|
return OperationResult.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OperationResult Repeat()
|
public OperationResult Repeat()
|
||||||
{
|
{
|
||||||
// TODO: Re-check if mandatory, if so, try to connect (if not connected) - otherwise, no action required (except maybe logging of status?)
|
// TODO: Re-check if mandatory, if so, try to connect (if not connected) - otherwise, no action required (except maybe logging of status?)
|
||||||
|
if (connected)
|
||||||
|
{
|
||||||
|
StopServiceSession();
|
||||||
|
StartServiceSession();
|
||||||
|
}
|
||||||
|
|
||||||
return OperationResult.Success;
|
return OperationResult.Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Revert()
|
public void Revert()
|
||||||
{
|
{
|
||||||
logger.Info("Closing service connection...");
|
logger.Info("Finalizing service session...");
|
||||||
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_CloseServiceConnection);
|
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_FinalizeServiceSession);
|
||||||
|
|
||||||
if (connected)
|
if (connected)
|
||||||
{
|
{
|
||||||
|
StopServiceSession();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
service.Disconnect();
|
service.Disconnect();
|
||||||
|
@ -88,6 +100,16 @@ namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void StartServiceSession()
|
||||||
|
{
|
||||||
|
service.StartSession(configuration.CurrentSession.Id, configuration.CurrentSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void StopServiceSession()
|
||||||
|
{
|
||||||
|
service.StopSession(configuration.CurrentSession.Id);
|
||||||
|
}
|
||||||
|
|
||||||
private void LogException(Exception e)
|
private void LogException(Exception e)
|
||||||
{
|
{
|
||||||
var message = "Failed to connect to the service component!";
|
var message = "Failed to connect to the service component!";
|
|
@ -0,0 +1,65 @@
|
||||||
|
/*
|
||||||
|
* 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.OperationModel;
|
||||||
|
using SafeExamBrowser.Contracts.Communication.Hosts;
|
||||||
|
using SafeExamBrowser.Contracts.Configuration;
|
||||||
|
using SafeExamBrowser.Contracts.I18n;
|
||||||
|
using SafeExamBrowser.Contracts.Logging;
|
||||||
|
using SafeExamBrowser.Contracts.UserInterface;
|
||||||
|
|
||||||
|
namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
||||||
|
{
|
||||||
|
internal class SessionInitializationOperation : IOperation
|
||||||
|
{
|
||||||
|
private IConfigurationRepository configuration;
|
||||||
|
private ILogger logger;
|
||||||
|
private IRuntimeHost runtimeHost;
|
||||||
|
|
||||||
|
public IProgressIndicator ProgressIndicator { private get; set; }
|
||||||
|
|
||||||
|
public SessionInitializationOperation(IConfigurationRepository configuration, ILogger logger, IRuntimeHost runtimeHost)
|
||||||
|
{
|
||||||
|
this.configuration = configuration;
|
||||||
|
this.logger = logger;
|
||||||
|
this.runtimeHost = runtimeHost;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OperationResult Perform()
|
||||||
|
{
|
||||||
|
InitializeSessionConfiguration();
|
||||||
|
|
||||||
|
return OperationResult.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OperationResult Repeat()
|
||||||
|
{
|
||||||
|
InitializeSessionConfiguration();
|
||||||
|
|
||||||
|
return OperationResult.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Revert()
|
||||||
|
{
|
||||||
|
// Nothing to do here...
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InitializeSessionConfiguration()
|
||||||
|
{
|
||||||
|
logger.Info("Initializing new session configuration...");
|
||||||
|
ProgressIndicator?.UpdateText(TextKey.ProgressIndicator_InitializeSession, true);
|
||||||
|
|
||||||
|
configuration.InitializeSessionConfiguration();
|
||||||
|
runtimeHost.StartupToken = configuration.CurrentSession.StartupToken;
|
||||||
|
|
||||||
|
logger.Info($" -> Client-ID: {configuration.RuntimeInfo.ClientId}");
|
||||||
|
logger.Info($" -> Runtime-ID: {configuration.RuntimeInfo.RuntimeId} (as reference, does not change)");
|
||||||
|
logger.Info($" -> Session-ID: {configuration.CurrentSession.Id}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,45 +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 SafeExamBrowser.Contracts.Behaviour.OperationModel;
|
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
|
||||||
{
|
|
||||||
internal class SessionSequenceEndOperation : IOperation
|
|
||||||
{
|
|
||||||
private SessionController controller;
|
|
||||||
|
|
||||||
public IProgressIndicator ProgressIndicator { private get; set; }
|
|
||||||
|
|
||||||
public SessionSequenceEndOperation(SessionController controller)
|
|
||||||
{
|
|
||||||
this.controller = controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OperationResult Perform()
|
|
||||||
{
|
|
||||||
controller.ProgressIndicator = ProgressIndicator;
|
|
||||||
|
|
||||||
return controller.StartSession();
|
|
||||||
}
|
|
||||||
|
|
||||||
public OperationResult Repeat()
|
|
||||||
{
|
|
||||||
controller.ProgressIndicator = ProgressIndicator;
|
|
||||||
|
|
||||||
return controller.StartSession();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Revert()
|
|
||||||
{
|
|
||||||
controller.ProgressIndicator = ProgressIndicator;
|
|
||||||
controller.StopSession();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,42 +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 SafeExamBrowser.Contracts.Behaviour.OperationModel;
|
|
||||||
using SafeExamBrowser.Contracts.UserInterface;
|
|
||||||
|
|
||||||
namespace SafeExamBrowser.Runtime.Behaviour.Operations
|
|
||||||
{
|
|
||||||
internal class SessionSequenceStartOperation : IOperation
|
|
||||||
{
|
|
||||||
private SessionController controller;
|
|
||||||
|
|
||||||
public IProgressIndicator ProgressIndicator { private get; set; }
|
|
||||||
|
|
||||||
public SessionSequenceStartOperation(SessionController controller)
|
|
||||||
{
|
|
||||||
this.controller = controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OperationResult Perform()
|
|
||||||
{
|
|
||||||
return OperationResult.Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public OperationResult Repeat()
|
|
||||||
{
|
|
||||||
controller.ProgressIndicator = ProgressIndicator;
|
|
||||||
|
|
||||||
return controller.StopSession();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Revert()
|
|
||||||
{
|
|
||||||
// Nothing to do here...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -209,18 +209,18 @@ namespace SafeExamBrowser.Runtime.Behaviour
|
||||||
runtimeHost.ShutdownRequested += RuntimeHost_ShutdownRequested;
|
runtimeHost.ShutdownRequested += RuntimeHost_ShutdownRequested;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RegisterSessionEvents()
|
|
||||||
{
|
|
||||||
configuration.CurrentSession.ClientProcess.Terminated += ClientProcess_Terminated;
|
|
||||||
configuration.CurrentSession.ClientProxy.ConnectionLost += Client_ConnectionLost;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DeregisterEvents()
|
private void DeregisterEvents()
|
||||||
{
|
{
|
||||||
runtimeHost.ReconfigurationRequested -= RuntimeHost_ReconfigurationRequested;
|
runtimeHost.ReconfigurationRequested -= RuntimeHost_ReconfigurationRequested;
|
||||||
runtimeHost.ShutdownRequested -= RuntimeHost_ShutdownRequested;
|
runtimeHost.ShutdownRequested -= RuntimeHost_ShutdownRequested;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void RegisterSessionEvents()
|
||||||
|
{
|
||||||
|
configuration.CurrentSession.ClientProcess.Terminated += ClientProcess_Terminated;
|
||||||
|
configuration.CurrentSession.ClientProxy.ConnectionLost += Client_ConnectionLost;
|
||||||
|
}
|
||||||
|
|
||||||
private void DeregisterSessionEvents()
|
private void DeregisterSessionEvents()
|
||||||
{
|
{
|
||||||
configuration.CurrentSession.ClientProcess.Terminated -= ClientProcess_Terminated;
|
configuration.CurrentSession.ClientProcess.Terminated -= ClientProcess_Terminated;
|
||||||
|
|
|
@ -54,7 +54,6 @@ namespace SafeExamBrowser.Runtime
|
||||||
var proxyFactory = new ProxyFactory(new ProxyObjectFactory(), logger);
|
var proxyFactory = new ProxyFactory(new ProxyObjectFactory(), logger);
|
||||||
var runtimeHost = new RuntimeHost(runtimeInfo.RuntimeAddress, configuration, new HostObjectFactory(), new ModuleLogger(logger, typeof(RuntimeHost)));
|
var runtimeHost = new RuntimeHost(runtimeInfo.RuntimeAddress, configuration, new HostObjectFactory(), new ModuleLogger(logger, typeof(RuntimeHost)));
|
||||||
var serviceProxy = new ServiceProxy(runtimeInfo.ServiceAddress, new ProxyObjectFactory(), new ModuleLogger(logger, typeof(ServiceProxy)));
|
var serviceProxy = new ServiceProxy(runtimeInfo.ServiceAddress, new ProxyObjectFactory(), new ModuleLogger(logger, typeof(ServiceProxy)));
|
||||||
var sessionController = new SessionController(configuration, logger, processFactory, proxyFactory, runtimeHost, serviceProxy);
|
|
||||||
|
|
||||||
var bootstrapOperations = new Queue<IOperation>();
|
var bootstrapOperations = new Queue<IOperation>();
|
||||||
var sessionOperations = new Queue<IOperation>();
|
var sessionOperations = new Queue<IOperation>();
|
||||||
|
@ -62,16 +61,17 @@ namespace SafeExamBrowser.Runtime
|
||||||
bootstrapOperations.Enqueue(new I18nOperation(logger, text));
|
bootstrapOperations.Enqueue(new I18nOperation(logger, text));
|
||||||
bootstrapOperations.Enqueue(new CommunicationOperation(runtimeHost, logger));
|
bootstrapOperations.Enqueue(new CommunicationOperation(runtimeHost, logger));
|
||||||
|
|
||||||
sessionOperations.Enqueue(new SessionSequenceStartOperation(sessionController));
|
|
||||||
sessionOperations.Enqueue(new ConfigurationOperation(configuration, logger, messageBox, runtimeInfo, text, args));
|
sessionOperations.Enqueue(new ConfigurationOperation(configuration, logger, messageBox, runtimeInfo, text, args));
|
||||||
sessionOperations.Enqueue(new ServiceConnectionOperation(configuration, logger, serviceProxy, text));
|
sessionOperations.Enqueue(new SessionInitializationOperation(configuration, logger, runtimeHost));
|
||||||
|
sessionOperations.Enqueue(new ServiceOperation(configuration, logger, serviceProxy, text));
|
||||||
|
sessionOperations.Enqueue(new ClientTerminationOperation(configuration, logger, processFactory, proxyFactory, runtimeHost));
|
||||||
sessionOperations.Enqueue(new KioskModeOperation(logger, configuration));
|
sessionOperations.Enqueue(new KioskModeOperation(logger, configuration));
|
||||||
sessionOperations.Enqueue(new SessionSequenceEndOperation(sessionController));
|
sessionOperations.Enqueue(new ClientOperation(configuration, logger, processFactory, proxyFactory, runtimeHost));
|
||||||
|
|
||||||
var boostrapSequence = new OperationSequence(logger, bootstrapOperations);
|
var bootstrapSequence = new OperationSequence(logger, bootstrapOperations);
|
||||||
var sessionSequence = new OperationSequence(logger, sessionOperations);
|
var sessionSequence = new OperationSequence(logger, sessionOperations);
|
||||||
|
|
||||||
RuntimeController = new RuntimeController(configuration, logger, messageBox, boostrapSequence, sessionSequence, runtimeHost, runtimeInfo, serviceProxy, shutdown, uiFactory);
|
RuntimeController = new RuntimeController(configuration, logger, messageBox, bootstrapSequence, sessionSequence, runtimeHost, runtimeInfo, serviceProxy, shutdown, uiFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void LogStartupInformation()
|
internal void LogStartupInformation()
|
||||||
|
|
|
@ -87,12 +87,12 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="App.cs" />
|
<Compile Include="App.cs" />
|
||||||
|
<Compile Include="Behaviour\Operations\ClientOperation.cs" />
|
||||||
|
<Compile Include="Behaviour\Operations\ClientTerminationOperation.cs" />
|
||||||
<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\ServiceConnectionOperation.cs" />
|
<Compile Include="Behaviour\Operations\ServiceOperation.cs" />
|
||||||
<Compile Include="Behaviour\Operations\SessionSequenceEndOperation.cs" />
|
<Compile Include="Behaviour\Operations\SessionInitializationOperation.cs" />
|
||||||
<Compile Include="Behaviour\SessionController.cs" />
|
|
||||||
<Compile Include="Behaviour\Operations\SessionSequenceStartOperation.cs" />
|
|
||||||
<Compile Include="Communication\ProxyFactory.cs" />
|
<Compile Include="Communication\ProxyFactory.cs" />
|
||||||
<Compile Include="Communication\RuntimeHost.cs" />
|
<Compile Include="Communication\RuntimeHost.cs" />
|
||||||
<Compile Include="CompositionRoot.cs" />
|
<Compile Include="CompositionRoot.cs" />
|
||||||
|
|
Loading…
Reference in a new issue