Files
C4IT-F4SD-Client/FasdDesktopUi/Basics/Services/RemoteDesktop/AgentRemoteDesktopService.cs

137 lines
6.1 KiB
C#

using C4IT.FASD.Cockpit.Communication;
using F4SD.Gamification.Services;
using FasdCockpitBase.Models.RemoteDesktopConnection;
using FasdCockpitCommunication.RemoteDesktopCommunication;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using static C4IT.Logging.cLogManager;
namespace FasdDesktopUi.Basics.Services.RemoteDesktop
{
internal static class AgentRemoteDesktopService
{
private static readonly Dictionary<Guid, Process> _viewerProcesses = new Dictionary<Guid, Process>();
internal static async Task<RemoteDesktopConnectionStatusResult> StartRemoteDesktopConnectionAsync(AgentRemoteClientInfo clientInfo, bool isElevated, CancellationToken token = default)
{
const int maxRetryCount = 20;
TimeSpan baseDelay = TimeSpan.FromSeconds(0.5);
AgentRemoteDesktopConnecitonDetails connectionDetails = await cFasdCockpitCommunicationBase.Instance.RemoteDesktopManager.InitiateConnection<AgentRemoteDesktopConnecitonDetails>(clientInfo, isElevated, token);
RemoteConnetionStatusChanged?.Invoke(null, RemoteDesktopConnectionStatus.Initiated);
if (token.IsCancellationRequested)
{
RemoteConnetionStatusChanged?.Invoke(null, RemoteDesktopConnectionStatus.Canceled);
return new RemoteDesktopConnectionStatusResult(RemoteDesktopConnectionStatus.Canceled);
}
if (connectionDetails is null)
{
LogEntry("Could not initiate remote connection.", C4IT.Logging.LogLevels.Warning);
return new RemoteDesktopConnectionStatusResult(RemoteDesktopConnectionStatus.Unknown);
}
if (connectionDetails.Errors != null && connectionDetails.Errors.Count > 0)
{
RemoteConnetionStatusChanged?.Invoke(null, RemoteDesktopConnectionStatus.Error);
return new RemoteDesktopConnectionStatusResult(RemoteDesktopConnectionStatus.Error) { Errors = connectionDetails.Errors.Select(e => e.Message).ToArray() };
}
RemoteDesktopConnectionStatusResult connectionStatus = null;
for (int i = 0; i < maxRetryCount; i++)
{
try
{
connectionStatus = await cFasdCockpitCommunicationBase.Instance.RemoteDesktopManager.GetConnectionStatus(connectionDetails.ConnectionId, token);
LogEntry($"Update {i} RemoteDesktop connection status: {connectionStatus}", C4IT.Logging.LogLevels.Debug);
if (token.IsCancellationRequested || IsRemoteConnectionEstablished(connectionStatus.Status))
break;
await Task.Delay(TimeSpan.FromTicks(baseDelay.Ticks * i));
}
catch (Exception ex)
{
LogException(ex);
}
}
if (token.IsCancellationRequested)
{
RemoteConnetionStatusChanged?.Invoke(null, RemoteDesktopConnectionStatus.Canceled);
return new RemoteDesktopConnectionStatusResult(RemoteDesktopConnectionStatus.Canceled);
}
RemoteConnetionStatusChanged?.Invoke(null, connectionStatus.Status);
if (connectionStatus.Status != RemoteDesktopConnectionStatus.Accepted)
{
LogEntry($"Could not connect to remote desktop. Status: {connectionStatus}", C4IT.Logging.LogLevels.Warning);
return new RemoteDesktopConnectionStatusResult(connectionStatus.Status);
}
StartViewer(connectionDetails);
GamificationService.TrackAction(F4SD.Gamification.CockpitAction.StartRemoteConnection);
return new RemoteDesktopConnectionStatusResult(RemoteDesktopConnectionStatus.Connected);
}
private static bool IsRemoteConnectionEstablished(RemoteDesktopConnectionStatus status)
{
switch (status)
{
case RemoteDesktopConnectionStatus.Accepted:
case RemoteDesktopConnectionStatus.Connected:
case RemoteDesktopConnectionStatus.Finished:
case RemoteDesktopConnectionStatus.Canceled:
return true;
case RemoteDesktopConnectionStatus.Unknown:
case RemoteDesktopConnectionStatus.Initiated:
default:
return false;
}
}
private static void StartViewer(AgentRemoteDesktopConnecitonDetails connectionDetails)
{
try
{
ProcessStartInfo info = new ProcessStartInfo(GetViewerPath())
{
Arguments = $"-connectionId {connectionDetails.ConnectionId} -phoenixServiceUrl {connectionDetails.PhoenixServiceUrl} -secret {connectionDetails.Secret} -hideAi {!cFasdCockpitConfig.Instance.Global.UseAiAnalyzer}"
};
Process process = Process.Start(info);
_viewerProcesses.Add(connectionDetails.ConnectionId, process);
RemoteConnetionStatusChanged?.Invoke(null, RemoteDesktopConnectionStatus.Connected);
}
catch (Exception ex)
{
LogException(ex);
}
}
internal static async Task StopRemoteDesktopConnection(Guid connectionId, CancellationToken token = default)
{
await cFasdCockpitCommunicationBase.Instance.RemoteDesktopManager.StopConnection(connectionId, token);
if (_viewerProcesses.TryGetValue(connectionId, out var process))
process.Close();
}
internal static string GetViewerPath()
{
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Phoenix\Phoenix.Viewer.exe").ToString();
}
internal static EventHandler<RemoteDesktopConnectionStatus> RemoteConnetionStatusChanged;
}
}