Remotely/Agent/Services/AppLauncherWin.cs
2021-07-29 07:56:44 -07:00

150 lines
7.1 KiB
C#

using Microsoft.AspNetCore.SignalR.Client;
using Remotely.Agent.Interfaces;
using Remotely.Shared.Models;
using Remotely.Shared.Utilities;
using Remotely.Shared.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
namespace Remotely.Agent.Services
{
public class AppLauncherWin : IAppLauncher
{
public AppLauncherWin(ConfigService configService)
{
ConnectionInfo = configService.GetConnectionInfo();
}
private ConnectionInfo ConnectionInfo { get; }
public async Task<int> LaunchChatService(string orgName, string requesterID, HubConnection hubConnection)
{
try
{
var rcBinaryPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Desktop", EnvironmentHelper.DesktopExecutableFileName);
if (!File.Exists(rcBinaryPath))
{
await hubConnection.SendAsync("DisplayMessage", "Chat executable not found on target device.", "Executable not found on device.", requesterID);
}
// Start Desktop app.
await hubConnection.SendAsync("DisplayMessage", $"Starting chat service...", "Starting chat service.", requesterID);
if (EnvironmentHelper.IsDebug)
{
return Process.Start(rcBinaryPath, $"-mode Chat -requester \"{requesterID}\" -organization \"{orgName}\"").Id;
}
else
{
var result = Win32Interop.OpenInteractiveProcess($"{rcBinaryPath} -mode Chat -requester \"{requesterID}\" -organization \"{orgName}\"",
targetSessionId: -1,
forceConsoleSession: false,
desktopName: "default",
hiddenWindow: false,
out var procInfo);
if (!result)
{
await hubConnection.SendAsync("DisplayMessage", "Chat service failed to start on target device.", "Failed to start chat service.", requesterID);
}
else
{
return procInfo.dwProcessId;
}
}
}
catch (Exception ex)
{
Logger.Write(ex);
await hubConnection.SendAsync("DisplayMessage", "Chat service failed to start on target device.", "Failed to start chat service.", requesterID);
}
return -1;
}
public async Task LaunchRemoteControl(int targetSessionId, string requesterID, string serviceID, HubConnection hubConnection)
{
try
{
var rcBinaryPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Desktop", EnvironmentHelper.DesktopExecutableFileName);
if (!File.Exists(rcBinaryPath))
{
await hubConnection.SendAsync("DisplayMessage", "Remote control executable not found on target device.", "Executable not found on device.", requesterID);
return;
}
// Start Desktop app.
await hubConnection.SendAsync("DisplayMessage", $"Starting remote control...", "Starting remote control.", requesterID);
if (EnvironmentHelper.IsDebug)
{
// SignalR Connection IDs might start with a hyphen. We surround them
// with quotes so the command line will be parsed correctly.
Process.Start(rcBinaryPath, $"-mode Unattended -requester \"{requesterID}\" -serviceid \"{serviceID}\" -deviceid {ConnectionInfo.DeviceID} -host {ConnectionInfo.Host}");
}
else
{
var result = Win32Interop.OpenInteractiveProcess(rcBinaryPath + $" -mode Unattended -requester \"{requesterID}\" -serviceid \"{serviceID}\" -deviceid {ConnectionInfo.DeviceID} -host {ConnectionInfo.Host}",
targetSessionId: targetSessionId,
forceConsoleSession: false,
desktopName: "default",
hiddenWindow: true,
out _);
if (!result)
{
await hubConnection.SendAsync("DisplayMessage", "Remote control failed to start on target device.", "Failed to start remote control.", requesterID);
}
}
}
catch (Exception ex)
{
Logger.Write(ex);
await hubConnection.SendAsync("DisplayMessage", "Remote control failed to start on target device.", "Failed to start remote control.", requesterID);
}
}
public async Task RestartScreenCaster(List<string> viewerIDs, string serviceID, string requesterID, HubConnection hubConnection, int targetSessionID = -1)
{
try
{
var rcBinaryPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Desktop", EnvironmentHelper.DesktopExecutableFileName);
// Start Desktop app.
Logger.Write("Restarting screen caster.");
if (EnvironmentHelper.IsDebug)
{
// SignalR Connection IDs might start with a hyphen. We surround them
// with quotes so the command line will be parsed correctly.
Process.Start(rcBinaryPath, $"-mode Unattended -requester \"{requesterID}\" -serviceid \"{serviceID}\" -deviceid {ConnectionInfo.DeviceID} -host {ConnectionInfo.Host} -relaunch true -viewers {String.Join(",", viewerIDs)}");
}
else
{
// Give a little time for session changing, etc.
await Task.Delay(1000);
var result = Win32Interop.OpenInteractiveProcess(rcBinaryPath + $" -mode Unattended -requester \"{requesterID}\" -serviceid \"{serviceID}\" -deviceid {ConnectionInfo.DeviceID} -host {ConnectionInfo.Host} -relaunch true -viewers {String.Join(",", viewerIDs)}",
targetSessionId: targetSessionID,
forceConsoleSession: Shlwapi.IsOS(OsType.OS_ANYSERVER) && targetSessionID == -1,
desktopName: "default",
hiddenWindow: true,
out _);
if (!result)
{
Logger.Write("Failed to relaunch screen caster.");
await hubConnection.SendAsync("SendConnectionFailedToViewers", viewerIDs);
await hubConnection.SendAsync("DisplayMessage", "Remote control failed to start on target device.", "Failed to start remote control.", requesterID);
}
}
}
catch (Exception ex)
{
await hubConnection.SendAsync("SendConnectionFailedToViewers", viewerIDs);
Logger.Write(ex);
throw;
}
}
}
}