137 lines
6.1 KiB
C#
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;
|
|
}
|
|
}
|