Remotely/Agent/Services/AppLauncherWin.cs
Jared Goodwin 3ef4cdf81a
Extract remote control functionality into separate library. (#539)
* Convert server to new single-file startup model.

* Add remote control implementations.

* Implement IViewerAuthorizer.

* Update hub endpoints.

* Implement HubEventHandler.

* Implement ViewerHubDataProvider.

* Implement page data provider.

* Implement RCL and refactor.

* Update submodule.

* Replace submodule with NuGet.

* Update copy URL.

* Update NuGet.

* Remove deprecated WebRTC.

* Remove deprecated WebRTC.

* Update Immense.RemoteControl

* Building out desktop projects.

* Bring more services into submodule.

* Update submodule.

* Update submodule.

* Refactoring for module.

* Update submodule.

* Update submodule

* Got Windows desktop app running.

* Refactor for submodule changes.

* FIx unattended session start.

* Switch desktop app out of console mode.

* Fix tests.

* Update publishing.

* Remove ClickOnce middleware.

* Remove ClickOnce remnants.

* Update submodule

* Add some logging.

* Update Linux path.

* Update submodule.

* Add cleanup service for unattended sessions that failed to start.

* Update submodule.

* Fix chat.

* Add ValidateExecutableReferencesMatchSelfContained property.

* Add other submodule projects.  Align checkbox.

* Update submodule.  Reduce deserialization in the browser, resulting in faster renders.

* Update submodule.

* Update submodule.

* Update submodule.

* Update submodule.

* Add orgId back for branding.

* Get branding loading in desktop apps.

* Update submodule.

* Create log dir.

* Refactor version check on config page.

* Update submodule.

* Update submodule.

* Change submodule URL.

* Correct namespace.

* Update submodule.

* Checkout submodules recursively.
2022-12-23 06:39:12 -08:00

221 lines
9.6 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.Runtime.Versioning;
using System.Security.Cryptography;
using System.Security.Principal;
using System.Threading.Tasks;
namespace Remotely.Agent.Services
{
[SupportedOSPlatform("windows")]
public class AppLauncherWin : IAppLauncher
{
private readonly ConnectionInfo _connectionInfo;
private readonly string _rcBinaryPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Desktop", EnvironmentHelper.DesktopExecutableFileName);
public AppLauncherWin(ConfigService configService)
{
_connectionInfo = configService.GetConnectionInfo();
}
public async Task<int> LaunchChatService(string pipeName, string userConnectionId, string requesterName, string orgName, string orgId, HubConnection hubConnection)
{
try
{
if (!File.Exists(_rcBinaryPath))
{
await hubConnection.SendAsync("DisplayMessage", "Chat executable not found on target device.", "Executable not found on device.", "bg-danger", userConnectionId);
}
// Start Desktop app.
await hubConnection.SendAsync("DisplayMessage", $"Starting chat service.", "Starting chat service.", "bg-success", userConnectionId);
if (WindowsIdentity.GetCurrent().IsSystem)
{
var result = Win32Interop.OpenInteractiveProcess(
_rcBinaryPath +
$" --mode Chat" +
$" --host \"{_connectionInfo.Host}\"" +
$" --pipe-name {pipeName}" +
$" --requester-name \"{requesterName}\"" +
$" --org-name \"{orgName}\"" +
$" --org-id \"{orgId}\"",
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.",
"bg-danger",
userConnectionId);
}
else
{
return procInfo.dwProcessId;
}
}
else
{
return Process.Start(_rcBinaryPath,
$" --mode Chat" +
$" --host \"{_connectionInfo.Host}\"" +
$" --requester-name \"{userConnectionId}\"" +
$" --org-name \"{orgName}\"" +
$" --org-id \"{orgId}\"" +
$" --pipe-name {pipeName}").Id;
}
}
catch (Exception ex)
{
Logger.Write(ex);
await hubConnection.SendAsync("DisplayMessage",
"Chat service failed to start on target device.",
"Failed to start chat service.",
"bg-danger",
userConnectionId);
}
return -1;
}
public async Task LaunchRemoteControl(int targetSessionId, string sessionId, string accessKey, string userConnectionId, string requesterName, string orgName, string orgId, HubConnection hubConnection)
{
try
{
if (!File.Exists(_rcBinaryPath))
{
await hubConnection.SendAsync("DisplayMessage",
"Remote control executable not found on target device.",
"Executable not found on device.",
"bg-danger",
userConnectionId);
return;
}
// Start Desktop app.
await hubConnection.SendAsync("DisplayMessage",
"Starting remote control.",
"Starting remote control.",
"bg-success",
userConnectionId);
if (WindowsIdentity.GetCurrent().IsSystem)
{
var result = Win32Interop.OpenInteractiveProcess(
_rcBinaryPath +
$" --mode Unattended" +
$" --host {_connectionInfo.Host}" +
$" --requester-name \"{requesterName}\"" +
$" --org-name \"{orgName}\"" +
$" --org-id \"{orgId}\"" +
$" --session-id \"{sessionId}\"" +
$" --access-key \"{accessKey}\"",
targetSessionId: targetSessionId,
forceConsoleSession: Shlwapi.IsOS(OsType.OS_ANYSERVER) && targetSessionId == -1,
desktopName: "default",
hiddenWindow: true,
out _);
if (!result)
{
await hubConnection.SendAsync("DisplayMessage",
"Remote control failed to start on target device.",
"Failed to start remote control.",
"bg-danger",
userConnectionId);
}
}
else
{
Process.Start(_rcBinaryPath,
$" --mode Unattended" +
$" --host {_connectionInfo.Host}" +
$" --requester-name \"{requesterName}\"" +
$" --org-name \"{orgName}\"" +
$" --org-id \"{orgId}\"" +
$" --session-id \"{sessionId}\"" +
$" --access-key \"{accessKey}\"");
}
}
catch (Exception ex)
{
Logger.Write(ex);
await hubConnection.SendAsync("DisplayMessage",
"Remote control failed to start on target device.",
"Failed to start remote control.",
"bg-danger",
userConnectionId);
}
}
public async Task RestartScreenCaster(List<string> viewerIDs, string sessionId, string accessKey, string userConnectionId, string requesterName, string orgName, string orgId, HubConnection hubConnection, int targetSessionID = -1)
{
try
{
// Start Desktop app.
Logger.Write("Restarting screen caster.");
if (WindowsIdentity.GetCurrent().IsSystem)
{
// Give a little time for session changing, etc.
await Task.Delay(1000);
var result = Win32Interop.OpenInteractiveProcess(_rcBinaryPath +
$" --mode Unattended" +
$" --relaunch true" +
$" --host {_connectionInfo.Host}" +
$" --requester-name \"{requesterName}\"" +
$" --org-name \"{orgName}\"" +
$" --org-id \"{orgId}\"" +
$" --session-id \"{sessionId}\"" +
$" --access-key \"{accessKey}\"" +
$" --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.",
"bg-danger",
userConnectionId);
}
}
else
{
Process.Start(_rcBinaryPath,
$" --mode Unattended" +
$" --relaunch true" +
$" --host {_connectionInfo.Host}" +
$" --requester-name \"{requesterName}\"" +
$" --org-name \"{orgName}\"" +
$" --org-id \"{orgId}\"" +
$" --session-id \"{sessionId}\"" +
$" --access-key \"{accessKey}\"" +
$" --viewers {string.Join(",", viewerIDs)}");
}
}
catch (Exception ex)
{
await hubConnection.SendAsync("SendConnectionFailedToViewers", viewerIDs);
Logger.Write(ex);
throw;
}
}
}
}