Move app exit event handlers. Add ReinstallAgent command.

This commit is contained in:
Jared 2020-12-19 11:52:36 -08:00 committed by Jared Goodwin
parent 3c88a88a5a
commit 0cf277ae87
8 changed files with 89 additions and 52 deletions

View File

@ -25,8 +25,9 @@ namespace Remotely.Agent.Services
Uninstaller uninstaller,
CommandExecutor commandExecutor,
ScriptRunner scriptRunner,
ChatClientService chatService,
IAppLauncher appLauncher,
ChatClientService chatService)
Updater updater)
{
ConfigService = configService;
Uninstaller = uninstaller;
@ -34,10 +35,12 @@ namespace Remotely.Agent.Services
ScriptRunner = scriptRunner;
AppLauncher = appLauncher;
ChatService = chatService;
Updater = updater;
}
public bool IsConnected => HubConnection?.State == HubConnectionState.Connected;
private IAppLauncher AppLauncher { get; }
private ChatClientService ChatService { get; }
private Updater Updater { get; }
private CommandExecutor CommandExecutor { get; }
private ConfigService ConfigService { get; }
private ConnectionInfo ConnectionInfo { get; set; }
@ -267,6 +270,11 @@ namespace Remotely.Agent.Services
await ScriptRunner.RunScript(mode, fileID, commandResultID, requesterID, HubConnection);
});
HubConnection.On("ReinstallAgent", async () =>
{
await Updater.InstallLatestVersion();
});
HubConnection.On("UninstallAgent", () =>
{
Uninstaller.UninstallAgent();

View File

@ -17,7 +17,8 @@ namespace Remotely.Agent.Services
}
private ConfigService ConfigService { get; }
private SemaphoreSlim UpdateLock { get; } = new SemaphoreSlim(1);
private SemaphoreSlim CheckForUpdatesLock { get; } = new SemaphoreSlim(1, 1);
private SemaphoreSlim InstallLatestVersionLock { get; } = new SemaphoreSlim(1, 1);
private System.Timers.Timer UpdateTimer { get; } = new System.Timers.Timer(TimeSpan.FromHours(6).TotalMilliseconds);
@ -33,11 +34,6 @@ namespace Remotely.Agent.Services
UpdateTimer.Start();
}
private async void UpdateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
await CheckForUpdates();
}
public async Task CheckForUpdates()
{
try
@ -47,7 +43,7 @@ namespace Remotely.Agent.Services
return;
}
await UpdateLock.WaitAsync();
await CheckForUpdatesLock.WaitAsync();
var connectionInfo = ConfigService.GetConnectionInfo();
var serverUrl = ConfigService.GetConnectionInfo().Host;
@ -104,15 +100,16 @@ namespace Remotely.Agent.Services
}
finally
{
UpdateLock.Release();
CheckForUpdatesLock.Release();
}
}
public async Task InstallLatestVersion()
{
try
{
await InstallLatestVersionLock.WaitAsync();
var connectionInfo = ConfigService.GetConnectionInfo();
var serverUrl = connectionInfo.Host;
@ -191,9 +188,16 @@ namespace Remotely.Agent.Services
{
Logger.Write(ex);
}
finally
{
InstallLatestVersionLock.Release();
}
}
private async void UpdateTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
await CheckForUpdates();
}
private class WebClientEx : WebClient
{
private readonly int _requestTimeout;

View File

@ -185,8 +185,6 @@ namespace Remotely.Desktop.Win
Logger.Write("Failed to set initial desktop.");
}
Win32Interop.SetMonitorState(User32.MonitorState.MonitorStateOn);
await SendReadyNotificationToViewers();
Services.GetRequiredService<IdleTimer>().Start();
CursorIconWatcher.OnChange += CursorIconWatcher_OnChange;

View File

@ -10,7 +10,6 @@ namespace Remotely.Desktop.Win.Services
{
public class ClipboardServiceWin : IClipboardService
{
private CancellationTokenSource _cancelTokenSource;
public event EventHandler<string> ClipboardTextChanged;
@ -19,15 +18,17 @@ namespace Remotely.Desktop.Win.Services
public void BeginWatching()
{
StopWatching();
_cancelTokenSource = new CancellationTokenSource();
App.Current.Dispatcher.Invoke(() =>
{
App.Current.Exit -= App_Exit;
App.Current.Exit += App_Exit;
});
StopWatching();
_cancelTokenSource = new CancellationTokenSource();
WatchClipboard(_cancelTokenSource.Token);
}

View File

@ -6,6 +6,7 @@ using Remotely.Shared.Win32;
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using static Remotely.Shared.Win32.User32;
@ -35,6 +36,12 @@ namespace Remotely.Desktop.Win.Services
public void Init()
{
App.Current.Dispatcher.Invoke(() =>
{
App.Current.Exit -= App_Exit;
App.Current.Exit += App_Exit;
});
StartInputProcessingThread();
}
@ -297,6 +304,7 @@ namespace Remotely.Desktop.Win.Services
CancelTokenSource?.Cancel();
CancelTokenSource?.Dispose();
// After BlockInput is enabled, only simulated input coming from the same thread
// will work. So we have to start a new thread that runs continuously and
// processes a queue of input events.
@ -305,12 +313,6 @@ namespace Remotely.Desktop.Win.Services
Logger.Write($"New input processing thread started on thread {Thread.CurrentThread.ManagedThreadId}.");
CancelTokenSource = new CancellationTokenSource();
App.Current.Dispatcher.Invoke(() =>
{
App.Current.Exit -= App_Exit;
App.Current.Exit += App_Exit;
});
if (inputBlocked)
{
ToggleBlockInput(true);

View File

@ -19,10 +19,9 @@ namespace Remotely.Desktop.Win.Services
public SessionIndicatorWin(Form backgroundForm)
{
BackgroundForm = backgroundForm;
Application.ApplicationExit += Application_ApplicationExit;
}
private void Application_ApplicationExit(object sender, EventArgs e)
private void App_Exit(object sender, EventArgs e)
{
notifyIcon?.Dispose();
}
@ -38,6 +37,8 @@ namespace Remotely.Desktop.Win.Services
return;
}
App.Current.Exit += App_Exit;
BackgroundForm.Invoke(new Action(() =>
{
container = new Container();

View File

@ -29,9 +29,9 @@ namespace Remotely.Server.Hubs
}
public static ConcurrentDictionary<string, RemotelyUser> ConnectionIdToUserLookup { get; } = new ConcurrentDictionary<string, RemotelyUser>();
private IHubContext<AgentHub> AgentHubContext { get; }
private IApplicationConfig AppConfig { get; }
private IDataService DataService { get; }
private IHubContext<AgentHub> AgentHubContext { get; }
private RemotelyUser RemotelyUser
{
get
@ -133,6 +133,18 @@ namespace Remotely.Server.Hubs
await base.OnDisconnectedAsync(exception);
}
public Task ReinstallAgents(string[] deviceIDs)
{
deviceIDs = DataService.FilterDeviceIDsByUserPermission(deviceIDs, RemotelyUser);
var connections = GetActiveClientConnections(deviceIDs);
foreach (var connection in connections)
{
AgentHubContext.Clients.Client(connection.Key).SendAsync("ReinstallAgent");
}
DataService.RemoveDevices(deviceIDs);
return Clients.Caller.SendAsync("RefreshDeviceList");
}
public async Task RemoteControl(string deviceID)
{
var targetDevice = AgentHub.ServiceConnections.FirstOrDefault(x => x.Value.ID == deviceID);
@ -168,6 +180,32 @@ namespace Remotely.Server.Hubs
}
public Task UninstallAgents(string[] deviceIDs)
{
deviceIDs = DataService.FilterDeviceIDsByUserPermission(deviceIDs, RemotelyUser);
var connections = GetActiveClientConnections(deviceIDs);
foreach (var connection in connections)
{
AgentHubContext.Clients.Client(connection.Key).SendAsync("UninstallAgent");
}
DataService.RemoveDevices(deviceIDs);
return Clients.Caller.SendAsync("RefreshDeviceList");
}
public Task UpdateTags(string deviceID, string tags)
{
if (DataService.DoesUserHaveAccessToDevice(deviceID, RemotelyUser))
{
if (tags.Length > 200)
{
return Clients.Caller.SendAsync("DisplayMessage", $"Tag must be 200 characters or less. Supplied length is {tags.Length}.", "Tag must be under 200 characters.");
}
DataService.UpdateTags(deviceID, tags);
return Clients.Caller.SendAsync("DisplayMessage", "Device updated successfully.", "Device updated.");
}
return Task.CompletedTask;
}
public Task UploadFiles(List<string> fileIDs, string transferID, string[] deviceIDs)
{
DataService.WriteEvent(new EventLog()
@ -185,31 +223,6 @@ namespace Remotely.Server.Hubs
}
return Task.CompletedTask;
}
public Task UninstallAgents(string[] deviceIDs)
{
deviceIDs = DataService.FilterDeviceIDsByUserPermission(deviceIDs, RemotelyUser);
var connections = GetActiveClientConnections(deviceIDs);
foreach (var connection in connections)
{
AgentHubContext.Clients.Client(connection.Key).SendAsync("UninstallAgent");
}
DataService.RemoveDevices(deviceIDs);
return Clients.Caller.SendAsync("RefreshDeviceList");
}
public Task UpdateTags(string deviceID, string tags)
{
if (DataService.DoesUserHaveAccessToDevice(deviceID, RemotelyUser))
{
if (tags.Length > 200)
{
return Clients.Caller.SendAsync("DisplayMessage", $"Tag must be 200 characters or less. Supplied length is {tags.Length}.", "Tag must be under 200 characters.");
}
DataService.UpdateTags(deviceID, tags);
return Clients.Caller.SendAsync("DisplayMessage", "Device updated successfully.", "Device updated.");
}
return Task.CompletedTask;
}
private IEnumerable<KeyValuePair<string, Device>> GetActiveClientConnections(string[] deviceIDs)
{
return AgentHub.ServiceConnections.Where(x =>

View File

@ -262,6 +262,16 @@ var commands: Array<ConsoleCommand> = [
AddConsoleOutput(output);
}
),
new ConsoleCommand("Reinstall",
[],
"Reinstalls the Remotely agent on the selected devices.",
"reinstall",
"",
(parameters, parameterDict) => {
var selectedDevices = DataGrid.GetSelectedDevices();
BrowserHubConnection.Connection.invoke("ReinstallAgents", selectedDevices.map(x => x.ID));
}
),
new ConsoleCommand(
"Remove",
[
@ -457,7 +467,7 @@ var commands: Array<ConsoleCommand> = [
),
new ConsoleCommand("Uninstall",
[],
"Uninstalls the Remotely client from the selected devices. Warning: This can't be undone from the web portal. You would need to redeploy the client.",
"Uninstalls the Remotely agent from the selected devices. Warning: This can't be undone from the web portal. You would need to redeploy the agent.",
"uninstall",
"",
(parameters, parameterDict) => {