From 4b634d8e9938b7e3be9632835dc4ae00ce26d34a Mon Sep 17 00:00:00 2001 From: dbuechel Date: Fri, 14 Dec 2018 12:31:31 +0100 Subject: [PATCH] SEBWIN-221: Implemented message box communication infrastructure and removed generic session start / stop error messages. --- SafeExamBrowser.Client/ClientController.cs | 12 +++++ .../Communication/ClientHost.cs | 12 +++-- .../Proxies/ClientProxy.cs | 27 ++++++++++ .../Proxies/RuntimeProxy.cs | 27 ++++++++++ .../Data/MessageBoxReplyMessage.cs | 36 +++++++++++++ .../Data/MessageBoxRequestMessage.cs | 54 +++++++++++++++++++ .../Events/MessageBoxReplyEventArgs.cs | 29 ++++++++++ .../Events/MessageBoxRequestEventArgs.cs | 44 +++++++++++++++ .../Communication/Hosts/IClientHost.cs | 5 ++ .../Communication/Hosts/IRuntimeHost.cs | 5 ++ .../Communication/ICommunication.cs | 2 + .../Communication/Proxies/IClientProxy.cs | 6 +++ .../Communication/Proxies/IRuntimeProxy.cs | 6 +++ SafeExamBrowser.Contracts/I18n/TextKey.cs | 4 -- .../SafeExamBrowser.Contracts.csproj | 4 ++ SafeExamBrowser.I18n/Text.xml | 12 ----- .../Communication/RuntimeHost.cs | 12 +++-- .../Operations/ConfigurationOperation.cs | 1 + SafeExamBrowser.Runtime/RuntimeController.cs | 35 ++++++++++-- 19 files changed, 305 insertions(+), 28 deletions(-) create mode 100644 SafeExamBrowser.Contracts/Communication/Data/MessageBoxReplyMessage.cs create mode 100644 SafeExamBrowser.Contracts/Communication/Data/MessageBoxRequestMessage.cs create mode 100644 SafeExamBrowser.Contracts/Communication/Events/MessageBoxReplyEventArgs.cs create mode 100644 SafeExamBrowser.Contracts/Communication/Events/MessageBoxRequestEventArgs.cs diff --git a/SafeExamBrowser.Client/ClientController.cs b/SafeExamBrowser.Client/ClientController.cs index a1675a2c..a71de664 100644 --- a/SafeExamBrowser.Client/ClientController.cs +++ b/SafeExamBrowser.Client/ClientController.cs @@ -160,6 +160,7 @@ namespace SafeExamBrowser.Client private void RegisterEvents() { Browser.ConfigurationDownloadRequested += Browser_ConfigurationDownloadRequested; + ClientHost.MessageBoxRequested += ClientHost_MessageBoxRequested; ClientHost.PasswordRequested += ClientHost_PasswordRequested; ClientHost.ReconfigurationDenied += ClientHost_ReconfigurationDenied; ClientHost.Shutdown += ClientHost_Shutdown; @@ -173,6 +174,7 @@ namespace SafeExamBrowser.Client private void DeregisterEvents() { Browser.ConfigurationDownloadRequested -= Browser_ConfigurationDownloadRequested; + ClientHost.MessageBoxRequested -= ClientHost_MessageBoxRequested; ClientHost.PasswordRequested -= ClientHost_PasswordRequested; ClientHost.ReconfigurationDenied -= ClientHost_ReconfigurationDenied; ClientHost.Shutdown -= ClientHost_Shutdown; @@ -259,6 +261,16 @@ namespace SafeExamBrowser.Client } } + private void ClientHost_MessageBoxRequested(MessageBoxRequestEventArgs args) + { + logger.Info($"Received message box request with id '{args.RequestId}'."); + + var result = messageBox.Show(args.Message, args.Title, args.Action, args.Icon); + + runtime.SubmitMessageBoxResult(args.RequestId, result); + logger.Info($"Message box request with id '{args.RequestId}' yielded result '{result}'."); + } + private void ClientHost_PasswordRequested(PasswordRequestEventArgs args) { var isAdmin = args.Purpose == PasswordRequestPurpose.Administrator; diff --git a/SafeExamBrowser.Client/Communication/ClientHost.cs b/SafeExamBrowser.Client/Communication/ClientHost.cs index c32b869c..e25eb2bc 100644 --- a/SafeExamBrowser.Client/Communication/ClientHost.cs +++ b/SafeExamBrowser.Client/Communication/ClientHost.cs @@ -23,6 +23,7 @@ namespace SafeExamBrowser.Client.Communication public Guid StartupToken { private get; set; } public bool IsConnected { get; private set; } + public event CommunicationEventHandler MessageBoxRequested; public event CommunicationEventHandler PasswordRequested; public event CommunicationEventHandler ReconfigurationDenied; public event CommunicationEventHandler RuntimeDisconnected; @@ -62,11 +63,14 @@ namespace SafeExamBrowser.Client.Communication { switch (message) { - case PasswordRequestMessage p: - PasswordRequested?.InvokeAsync(new PasswordRequestEventArgs { Purpose = p.Purpose, RequestId = p.RequestId }); + case MessageBoxRequestMessage m: + MessageBoxRequested?.InvokeAsync(new MessageBoxRequestEventArgs { Action = m.Action, Icon = m.Icon, Message = m.Message, RequestId = m.RequestId, Title = m.Title }); return new SimpleResponse(SimpleResponsePurport.Acknowledged); - case ReconfigurationDeniedMessage r: - ReconfigurationDenied?.InvokeAsync(new ReconfigurationEventArgs { ConfigurationPath = r.FilePath }); + case PasswordRequestMessage m: + PasswordRequested?.InvokeAsync(new PasswordRequestEventArgs { Purpose = m.Purpose, RequestId = m.RequestId }); + return new SimpleResponse(SimpleResponsePurport.Acknowledged); + case ReconfigurationDeniedMessage m: + ReconfigurationDenied?.InvokeAsync(new ReconfigurationEventArgs { ConfigurationPath = m.FilePath }); return new SimpleResponse(SimpleResponsePurport.Acknowledged); } diff --git a/SafeExamBrowser.Communication/Proxies/ClientProxy.cs b/SafeExamBrowser.Communication/Proxies/ClientProxy.cs index f3d93a01..4da1a073 100644 --- a/SafeExamBrowser.Communication/Proxies/ClientProxy.cs +++ b/SafeExamBrowser.Communication/Proxies/ClientProxy.cs @@ -10,6 +10,7 @@ using System; using SafeExamBrowser.Contracts.Communication.Data; using SafeExamBrowser.Contracts.Communication.Proxies; using SafeExamBrowser.Contracts.Logging; +using SafeExamBrowser.Contracts.UserInterface.MessageBox; namespace SafeExamBrowser.Communication.Proxies { @@ -125,5 +126,31 @@ namespace SafeExamBrowser.Communication.Proxies return new CommunicationResult(false); } } + + public CommunicationResult ShowMessage(string message, string title, MessageBoxAction action, MessageBoxIcon icon, Guid requestId) + { + try + { + var response = Send(new MessageBoxRequestMessage(action, icon, message, requestId, title)); + var success = IsAcknowledged(response); + + if (success) + { + Logger.Debug("Client acknowledged message box request."); + } + else + { + Logger.Error($"Client did not acknowledge message box request! Received: {ToString(response)}."); + } + + return new CommunicationResult(success); + } + catch (Exception e) + { + Logger.Error($"Failed to perform '{nameof(ShowMessage)}'", e); + + return new CommunicationResult(false); + } + } } } diff --git a/SafeExamBrowser.Communication/Proxies/RuntimeProxy.cs b/SafeExamBrowser.Communication/Proxies/RuntimeProxy.cs index afa78715..9aba7f81 100644 --- a/SafeExamBrowser.Communication/Proxies/RuntimeProxy.cs +++ b/SafeExamBrowser.Communication/Proxies/RuntimeProxy.cs @@ -10,6 +10,7 @@ using System; using SafeExamBrowser.Contracts.Communication.Data; using SafeExamBrowser.Contracts.Communication.Proxies; using SafeExamBrowser.Contracts.Logging; +using SafeExamBrowser.Contracts.UserInterface.MessageBox; namespace SafeExamBrowser.Communication.Proxies { @@ -126,6 +127,32 @@ namespace SafeExamBrowser.Communication.Proxies } } + public CommunicationResult SubmitMessageBoxResult(Guid requestId, MessageBoxResult result) + { + try + { + var response = Send(new MessageBoxReplyMessage(requestId, result)); + var acknowledged = IsAcknowledged(response); + + if (acknowledged) + { + Logger.Debug("Runtime acknowledged message box result transmission."); + } + else + { + Logger.Error($"Runtime did not acknowledge message box result transmission! Response: {ToString(response)}."); + } + + return new CommunicationResult(acknowledged); + } + catch (Exception e) + { + Logger.Error($"Failed to perform '{nameof(SubmitMessageBoxResult)}'", e); + + return new CommunicationResult(false); + } + } + public CommunicationResult SubmitPassword(Guid requestId, bool success, string password = null) { try diff --git a/SafeExamBrowser.Contracts/Communication/Data/MessageBoxReplyMessage.cs b/SafeExamBrowser.Contracts/Communication/Data/MessageBoxReplyMessage.cs new file mode 100644 index 00000000..b783fcb1 --- /dev/null +++ b/SafeExamBrowser.Contracts/Communication/Data/MessageBoxReplyMessage.cs @@ -0,0 +1,36 @@ +/* + * 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.UserInterface.MessageBox; + +namespace SafeExamBrowser.Contracts.Communication.Data +{ + /// + /// The reply to a . + /// + [Serializable] + public class MessageBoxReplyMessage : Message + { + /// + /// Identifies the message box request. + /// + public Guid RequestId { get; private set; } + + /// + /// The result of the interaction. + /// + public MessageBoxResult Result { get; private set; } + + public MessageBoxReplyMessage(Guid requestId, MessageBoxResult result) + { + RequestId = requestId; + Result = result; + } + } +} diff --git a/SafeExamBrowser.Contracts/Communication/Data/MessageBoxRequestMessage.cs b/SafeExamBrowser.Contracts/Communication/Data/MessageBoxRequestMessage.cs new file mode 100644 index 00000000..cf50eb38 --- /dev/null +++ b/SafeExamBrowser.Contracts/Communication/Data/MessageBoxRequestMessage.cs @@ -0,0 +1,54 @@ +/* + * 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.UserInterface.MessageBox; + +namespace SafeExamBrowser.Contracts.Communication.Data +{ + /// + /// This message is transmitted to the client to request a message box input by the user. + /// + [Serializable] + public class MessageBoxRequestMessage : Message + { + /// + /// The action to be displayed. + /// + public MessageBoxAction Action { get; private set; } + + /// + /// The icon to be displayed. + /// + public MessageBoxIcon Icon { get; private set; } + + /// + /// The message to be displayed. + /// + public string Message { get; private set; } + + /// + /// Identifies the message box request. + /// + public Guid RequestId { get; private set; } + + /// + /// The title to be displayed. + /// + public string Title { get; private set; } + + public MessageBoxRequestMessage(MessageBoxAction action, MessageBoxIcon icon, string message, Guid requestId, string title) + { + Action = action; + Icon = icon; + Message = message; + RequestId = requestId; + Title = title; + } + } +} diff --git a/SafeExamBrowser.Contracts/Communication/Events/MessageBoxReplyEventArgs.cs b/SafeExamBrowser.Contracts/Communication/Events/MessageBoxReplyEventArgs.cs new file mode 100644 index 00000000..d21b43e8 --- /dev/null +++ b/SafeExamBrowser.Contracts/Communication/Events/MessageBoxReplyEventArgs.cs @@ -0,0 +1,29 @@ +/* + * 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.UserInterface.MessageBox; + +namespace SafeExamBrowser.Contracts.Communication.Events +{ + /// + /// The event arguments used for the message box reply event fired by the . + /// + public class MessageBoxReplyEventArgs : CommunicationEventArgs + { + /// + /// Identifies the message box request. + /// + public Guid RequestId { get; set; } + + /// + /// The result of the interaction. + /// + public MessageBoxResult Result { get; set; } + } +} diff --git a/SafeExamBrowser.Contracts/Communication/Events/MessageBoxRequestEventArgs.cs b/SafeExamBrowser.Contracts/Communication/Events/MessageBoxRequestEventArgs.cs new file mode 100644 index 00000000..7e99f3dd --- /dev/null +++ b/SafeExamBrowser.Contracts/Communication/Events/MessageBoxRequestEventArgs.cs @@ -0,0 +1,44 @@ +/* + * 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.UserInterface.MessageBox; + +namespace SafeExamBrowser.Contracts.Communication.Events +{ + /// + /// The event arguments used for the message box request event fired by the . + /// + public class MessageBoxRequestEventArgs : CommunicationEventArgs + { + /// + /// The action to be displayed. + /// + public MessageBoxAction Action { get; set; } + + /// + /// The icon to be displayed. + /// + public MessageBoxIcon Icon { get; set; } + + /// + /// The message to be displayed. + /// + public string Message { get; set; } + + /// + /// Identifies the message box request. + /// + public Guid RequestId { get; set; } + + /// + /// The title to be displayed. + /// + public string Title { get; set; } + } +} diff --git a/SafeExamBrowser.Contracts/Communication/Hosts/IClientHost.cs b/SafeExamBrowser.Contracts/Communication/Hosts/IClientHost.cs index cd89b698..ef8b69cf 100644 --- a/SafeExamBrowser.Contracts/Communication/Hosts/IClientHost.cs +++ b/SafeExamBrowser.Contracts/Communication/Hosts/IClientHost.cs @@ -26,6 +26,11 @@ namespace SafeExamBrowser.Contracts.Communication.Hosts /// Guid StartupToken { set; } + /// + /// Event fired when the runtime requests a message box input from the user. + /// + event CommunicationEventHandler MessageBoxRequested; + /// /// Event fired when the runtime requests a password input from the user. /// diff --git a/SafeExamBrowser.Contracts/Communication/Hosts/IRuntimeHost.cs b/SafeExamBrowser.Contracts/Communication/Hosts/IRuntimeHost.cs index 6ffaf821..4212d50a 100644 --- a/SafeExamBrowser.Contracts/Communication/Hosts/IRuntimeHost.cs +++ b/SafeExamBrowser.Contracts/Communication/Hosts/IRuntimeHost.cs @@ -41,6 +41,11 @@ namespace SafeExamBrowser.Contracts.Communication.Hosts /// event CommunicationEventHandler ClientConfigurationNeeded; + /// + /// Event fired when the client submitted a message box result chosen by the user. + /// + event CommunicationEventHandler MessageBoxReplyReceived; + /// /// Event fired when the client submitted a password entered by the user. /// diff --git a/SafeExamBrowser.Contracts/Communication/ICommunication.cs b/SafeExamBrowser.Contracts/Communication/ICommunication.cs index 0b984fb4..3c1ed1b2 100644 --- a/SafeExamBrowser.Contracts/Communication/ICommunication.cs +++ b/SafeExamBrowser.Contracts/Communication/ICommunication.cs @@ -20,6 +20,8 @@ namespace SafeExamBrowser.Contracts.Communication [ServiceKnownType(typeof(AuthenticationResponse))] [ServiceKnownType(typeof(ClientConfiguration))] [ServiceKnownType(typeof(ConfigurationResponse))] + [ServiceKnownType(typeof(MessageBoxReplyMessage))] + [ServiceKnownType(typeof(MessageBoxRequestMessage))] [ServiceKnownType(typeof(PasswordReplyMessage))] [ServiceKnownType(typeof(PasswordRequestMessage))] [ServiceKnownType(typeof(ReconfigurationMessage))] diff --git a/SafeExamBrowser.Contracts/Communication/Proxies/IClientProxy.cs b/SafeExamBrowser.Contracts/Communication/Proxies/IClientProxy.cs index 9f3c049e..35e0caa0 100644 --- a/SafeExamBrowser.Contracts/Communication/Proxies/IClientProxy.cs +++ b/SafeExamBrowser.Contracts/Communication/Proxies/IClientProxy.cs @@ -8,6 +8,7 @@ using System; using SafeExamBrowser.Contracts.Communication.Data; +using SafeExamBrowser.Contracts.UserInterface.MessageBox; namespace SafeExamBrowser.Contracts.Communication.Proxies { @@ -35,5 +36,10 @@ namespace SafeExamBrowser.Contracts.Communication.Proxies /// Requests the client to render a password dialog and subsequently return the interaction result as separate message. /// CommunicationResult RequestPassword(PasswordRequestPurpose purpose, Guid requestId); + + /// + /// Requests the client to render a message box and subsequently return the interaction result as separate message. + /// + CommunicationResult ShowMessage(string message, string title, MessageBoxAction action, MessageBoxIcon icon, Guid requestId); } } diff --git a/SafeExamBrowser.Contracts/Communication/Proxies/IRuntimeProxy.cs b/SafeExamBrowser.Contracts/Communication/Proxies/IRuntimeProxy.cs index 5140e5c4..ddfb4e46 100644 --- a/SafeExamBrowser.Contracts/Communication/Proxies/IRuntimeProxy.cs +++ b/SafeExamBrowser.Contracts/Communication/Proxies/IRuntimeProxy.cs @@ -8,6 +8,7 @@ using System; using SafeExamBrowser.Contracts.Communication.Data; +using SafeExamBrowser.Contracts.UserInterface.MessageBox; namespace SafeExamBrowser.Contracts.Communication.Proxies { @@ -36,6 +37,11 @@ namespace SafeExamBrowser.Contracts.Communication.Proxies /// CommunicationResult RequestReconfiguration(string filePath); + /// + /// Submits the result of a message box input previously requested by the runtime. + /// + CommunicationResult SubmitMessageBoxResult(Guid requestId, MessageBoxResult result); + /// /// Submits the result of a password input previously requested by the runtime. If the procedure was aborted by the user, /// the password parameter will be null! diff --git a/SafeExamBrowser.Contracts/I18n/TextKey.cs b/SafeExamBrowser.Contracts/I18n/TextKey.cs index c9372abf..71ad3213 100644 --- a/SafeExamBrowser.Contracts/I18n/TextKey.cs +++ b/SafeExamBrowser.Contracts/I18n/TextKey.cs @@ -38,10 +38,6 @@ namespace SafeExamBrowser.Contracts.I18n MessageBox_ReconfigurationErrorTitle, MessageBox_ReconfigurationQuestion, MessageBox_ReconfigurationQuestionTitle, - MessageBox_SessionStartError, - MessageBox_SessionStartErrorTitle, - MessageBox_SessionStopError, - MessageBox_SessionStopErrorTitle, MessageBox_ShutdownError, MessageBox_ShutdownErrorTitle, MessageBox_SingleInstance, diff --git a/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj b/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj index ccc6ab3d..87a5303d 100644 --- a/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj +++ b/SafeExamBrowser.Contracts/SafeExamBrowser.Contracts.csproj @@ -52,7 +52,11 @@ + + + + diff --git a/SafeExamBrowser.I18n/Text.xml b/SafeExamBrowser.I18n/Text.xml index a0defa0c..37eb700b 100644 --- a/SafeExamBrowser.I18n/Text.xml +++ b/SafeExamBrowser.I18n/Text.xml @@ -72,18 +72,6 @@ Configuration Detected - - The application failed to start a new session. Please consult the application log for more information... - - - Session Start Error - - - The application failed to properly stop the running session. Please consult the application log for more information... - - - Session Stop Error - An unexpected error occurred during the shutdown procedure! Please consult the application log for more information... diff --git a/SafeExamBrowser.Runtime/Communication/RuntimeHost.cs b/SafeExamBrowser.Runtime/Communication/RuntimeHost.cs index 7f5dbbed..77934c95 100644 --- a/SafeExamBrowser.Runtime/Communication/RuntimeHost.cs +++ b/SafeExamBrowser.Runtime/Communication/RuntimeHost.cs @@ -23,6 +23,7 @@ namespace SafeExamBrowser.Runtime.Communication public event CommunicationEventHandler ClientDisconnected; public event CommunicationEventHandler ClientReady; public event CommunicationEventHandler ClientConfigurationNeeded; + public event CommunicationEventHandler MessageBoxReplyReceived; public event CommunicationEventHandler PasswordReceived; public event CommunicationEventHandler ReconfigurationRequested; public event CommunicationEventHandler ShutdownRequested; @@ -53,11 +54,14 @@ namespace SafeExamBrowser.Runtime.Communication { switch (message) { - case PasswordReplyMessage r: - PasswordReceived?.InvokeAsync(new PasswordReplyEventArgs { Password = r.Password, RequestId = r.RequestId, Success = r.Success }); + case MessageBoxReplyMessage m: + MessageBoxReplyReceived?.InvokeAsync(new MessageBoxReplyEventArgs { RequestId = m.RequestId, Result = m.Result }); return new SimpleResponse(SimpleResponsePurport.Acknowledged); - case ReconfigurationMessage r: - ReconfigurationRequested?.InvokeAsync(new ReconfigurationEventArgs { ConfigurationPath = r.ConfigurationPath }); + case PasswordReplyMessage m: + PasswordReceived?.InvokeAsync(new PasswordReplyEventArgs { Password = m.Password, RequestId = m.RequestId, Success = m.Success }); + return new SimpleResponse(SimpleResponsePurport.Acknowledged); + case ReconfigurationMessage m: + ReconfigurationRequested?.InvokeAsync(new ReconfigurationEventArgs { ConfigurationPath = m.ConfigurationPath }); return new SimpleResponse(SimpleResponsePurport.Acknowledged); } diff --git a/SafeExamBrowser.Runtime/Operations/ConfigurationOperation.cs b/SafeExamBrowser.Runtime/Operations/ConfigurationOperation.cs index 54ec32bb..ef62713b 100644 --- a/SafeExamBrowser.Runtime/Operations/ConfigurationOperation.cs +++ b/SafeExamBrowser.Runtime/Operations/ConfigurationOperation.cs @@ -273,6 +273,7 @@ namespace SafeExamBrowser.Runtime.Operations else { logger.Info("Authentication has failed!"); + ActionRequired?.Invoke(new InvalidPasswordMessageArgs()); return OperationResult.Failed; } diff --git a/SafeExamBrowser.Runtime/RuntimeController.cs b/SafeExamBrowser.Runtime/RuntimeController.cs index 1ceec82c..7ef4bd65 100644 --- a/SafeExamBrowser.Runtime/RuntimeController.cs +++ b/SafeExamBrowser.Runtime/RuntimeController.cs @@ -207,9 +207,7 @@ namespace SafeExamBrowser.Runtime { StopSession(); - messageBox.Show(TextKey.MessageBox_SessionStartError, TextKey.MessageBox_SessionStartErrorTitle, icon: MessageBoxIcon.Error, parent: runtimeWindow); logger.Info("Terminating application..."); - shutdown.Invoke(); } } @@ -247,7 +245,6 @@ namespace SafeExamBrowser.Runtime else { logger.Info("### --- Session Stop Failed --- ###"); - messageBox.Show(TextKey.MessageBox_SessionStopError, TextKey.MessageBox_SessionStopErrorTitle, icon: MessageBoxIcon.Error, parent: runtimeWindow); } } @@ -419,10 +416,40 @@ namespace SafeExamBrowser.Runtime } else { - // TODO + ShowMessageBoxViaClient(message, title, MessageBoxAction.Confirm, args.Icon); } } + private MessageBoxResult ShowMessageBoxViaClient(string message, string title, MessageBoxAction confirm, MessageBoxIcon icon) + { + var requestId = Guid.NewGuid(); + var result = MessageBoxResult.None; + var response = default(MessageBoxReplyEventArgs); + var responseEvent = new AutoResetEvent(false); + var responseEventHandler = new CommunicationEventHandler((args) => + { + if (args.RequestId == requestId) + { + response = args; + responseEvent.Set(); + } + }); + + runtimeHost.MessageBoxReplyReceived += responseEventHandler; + + var communication = sessionContext.ClientProxy.ShowMessage(message, title, MessageBoxAction.Confirm, icon, requestId); + + if (communication.Success) + { + responseEvent.WaitOne(); + result = response.Result; + } + + runtimeHost.MessageBoxReplyReceived -= responseEventHandler; + + return result; + } + private void TryGetPasswordViaDialog(PasswordRequiredEventArgs args) { var isAdmin = args.Purpose == PasswordRequestPurpose.Administrator;