Skip to content

Commit 1afcc8c

Browse files
committed
Bring in submodule files.
1 parent 5c2085f commit 1afcc8c

File tree

387 files changed

+61448
-6573
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

387 files changed

+61448
-6573
lines changed

.gitmodules

-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +0,0 @@
1-
[submodule "submodules/Immense.RemoteControl"]
2-
path = submodules/Immense.RemoteControl
3-
url = git@github.com:immense/RemoteControl.git

Agent/Agent.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939
</ItemGroup>
4040

4141
<ItemGroup>
42+
<ProjectReference Include="..\Desktop.Native\Desktop.Native.csproj" />
4243
<ProjectReference Include="..\Shared\Shared.csproj" />
43-
<ProjectReference Include="..\submodules\Immense.RemoteControl\Immense.RemoteControl.Desktop.Shared\Immense.RemoteControl.Desktop.Shared.csproj" />
4444
</ItemGroup>
4545

4646

Agent/Services/ChatClientService.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using Immense.RemoteControl.Shared.Models;
2-
using Microsoft.AspNetCore.SignalR.Client;
1+
using Microsoft.AspNetCore.SignalR.Client;
32
using Microsoft.Extensions.Logging;
43
using Remotely.Agent.Interfaces;
54
using Remotely.Agent.Models;

Agent/Services/Linux/AppLauncherLinux.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
using Immense.RemoteControl.Shared;
2-
using Microsoft.AspNetCore.SignalR.Client;
1+
using Microsoft.AspNetCore.SignalR.Client;
32
using Microsoft.Extensions.Logging;
43
using Remotely.Agent.Interfaces;
54
using Remotely.Shared.Extensions;
65
using Remotely.Shared.Models;
6+
using Remotely.Shared.Primitives;
77
using Remotely.Shared.Services;
88
using Remotely.Shared.Utilities;
99
using System;

Desktop.Linux/Desktop.Linux.csproj

+1-3
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,6 @@
5656
</ItemGroup>
5757
<ItemGroup>
5858
<ProjectReference Include="..\Desktop.Shared\Desktop.Shared.csproj" />
59-
<ProjectReference Include="..\submodules\Immense.RemoteControl\Immense.RemoteControl.Desktop.Linux\Immense.RemoteControl.Desktop.Linux.csproj" />
60-
<ProjectReference Include="..\submodules\Immense.RemoteControl\Immense.RemoteControl.Desktop.Shared\Immense.RemoteControl.Desktop.Shared.csproj" />
61-
<ProjectReference Include="..\submodules\Immense.RemoteControl\Immense.RemoteControl.Desktop.UI\Immense.RemoteControl.Desktop.UI.csproj" />
59+
<ProjectReference Include="..\Desktop.UI\Desktop.UI.csproj" />
6260
</ItemGroup>
6361
</Project>

Desktop.Linux/Services/AppStartup.cs

+150
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
using Immense.RemoteControl.Desktop.Shared.Abstractions;
2+
using Immense.RemoteControl.Desktop.Shared.Enums;
3+
using Immense.RemoteControl.Desktop.Shared.Services;
4+
using Immense.RemoteControl.Desktop.UI.Services;
5+
using Immense.RemoteControl.Shared.Models;
6+
using Microsoft.Extensions.Logging;
7+
8+
namespace Immense.RemoteControl.Desktop.Linux.Services;
9+
10+
internal class AppStartup : IAppStartup
11+
{
12+
private readonly IAppState _appState;
13+
private readonly IKeyboardMouseInput _inputService;
14+
private readonly IDesktopHubConnection _desktopHub;
15+
private readonly IClipboardService _clipboardService;
16+
private readonly IChatHostService _chatHostService;
17+
private readonly ICursorIconWatcher _cursorIconWatcher;
18+
private readonly IUiDispatcher _dispatcher;
19+
private readonly IIdleTimer _idleTimer;
20+
private readonly IShutdownService _shutdownService;
21+
private readonly IBrandingProvider _brandingProvider;
22+
private readonly ILogger<AppStartup> _logger;
23+
24+
public AppStartup(
25+
IAppState appState,
26+
IKeyboardMouseInput inputService,
27+
IDesktopHubConnection desktopHub,
28+
IClipboardService clipboardService,
29+
IChatHostService chatHostService,
30+
ICursorIconWatcher iconWatcher,
31+
IUiDispatcher dispatcher,
32+
IIdleTimer idleTimer,
33+
IShutdownService shutdownService,
34+
IBrandingProvider brandingProvider,
35+
ILogger<AppStartup> logger)
36+
{
37+
_appState = appState;
38+
_inputService = inputService;
39+
_desktopHub = desktopHub;
40+
_clipboardService = clipboardService;
41+
_chatHostService = chatHostService;
42+
_cursorIconWatcher = iconWatcher;
43+
_dispatcher = dispatcher;
44+
_idleTimer = idleTimer;
45+
_shutdownService = shutdownService;
46+
_brandingProvider = brandingProvider;
47+
_logger = logger;
48+
}
49+
50+
public async Task Run()
51+
{
52+
await _brandingProvider.Initialize();
53+
54+
if (_appState.Mode is AppMode.Unattended or AppMode.Attended)
55+
{
56+
_clipboardService.BeginWatching();
57+
_inputService.Init();
58+
_cursorIconWatcher.OnChange += CursorIconWatcher_OnChange;
59+
}
60+
61+
switch (_appState.Mode)
62+
{
63+
case AppMode.Unattended:
64+
{
65+
var result = await _dispatcher.StartHeadless();
66+
if (!result.IsSuccess)
67+
{
68+
return;
69+
}
70+
await StartScreenCasting().ConfigureAwait(false);
71+
break;
72+
}
73+
case AppMode.Attended:
74+
{
75+
_dispatcher.StartClassicDesktop();
76+
break;
77+
}
78+
case AppMode.Chat:
79+
{
80+
var result = await _dispatcher.StartHeadless();
81+
if (!result.IsSuccess)
82+
{
83+
return;
84+
}
85+
await _chatHostService
86+
.StartChat(_appState.PipeName, _appState.OrganizationName)
87+
.ConfigureAwait(false);
88+
break;
89+
}
90+
default:
91+
break;
92+
}
93+
}
94+
95+
96+
private async Task StartScreenCasting()
97+
{
98+
if (!await _desktopHub.Connect(TimeSpan.FromSeconds(30), _dispatcher.ApplicationExitingToken))
99+
{
100+
await _shutdownService.Shutdown();
101+
return;
102+
}
103+
104+
var result = await _desktopHub.SendUnattendedSessionInfo(
105+
_appState.SessionId,
106+
_appState.AccessKey,
107+
Environment.MachineName,
108+
_appState.RequesterName,
109+
_appState.OrganizationName);
110+
111+
if (!result.IsSuccess)
112+
{
113+
_logger.LogError(result.Exception, "An error occurred while trying to establish a session with the server.");
114+
await _shutdownService.Shutdown();
115+
return;
116+
}
117+
118+
try
119+
{
120+
if (_appState.ArgDict.ContainsKey("relaunch"))
121+
{
122+
_logger.LogInformation("Resuming after relaunch.");
123+
var viewerIDs = _appState.RelaunchViewers;
124+
await _desktopHub.NotifyViewersRelaunchedScreenCasterReady(viewerIDs);
125+
}
126+
else
127+
{
128+
await _desktopHub.NotifyRequesterUnattendedReady();
129+
}
130+
}
131+
finally
132+
{
133+
_idleTimer.Start();
134+
}
135+
}
136+
137+
138+
139+
private async void CursorIconWatcher_OnChange(object? sender, CursorInfo cursor)
140+
{
141+
if (_appState.Viewers.Any() == true &&
142+
_desktopHub.IsConnected)
143+
{
144+
foreach (var viewer in _appState.Viewers.Values)
145+
{
146+
await viewer.SendCursorChange(cursor);
147+
}
148+
}
149+
}
150+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using Immense.RemoteControl.Desktop.Shared.Abstractions;
2+
3+
namespace Immense.RemoteControl.Desktop.Linux.Services;
4+
5+
public class AudioCapturerLinux : IAudioCapturer
6+
{
7+
#pragma warning disable CS0067
8+
public event EventHandler<byte[]>? AudioSampleReady;
9+
#pragma warning restore
10+
11+
public void ToggleAudio(bool toggleOn)
12+
{
13+
// Not implemented.
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using Immense.RemoteControl.Desktop.Shared.Abstractions;
2+
using Immense.RemoteControl.Shared.Models;
3+
using System.Drawing;
4+
5+
namespace Immense.RemoteControl.Desktop.Linux.Services;
6+
7+
public class CursorIconWatcherLinux : ICursorIconWatcher
8+
{
9+
#pragma warning disable CS0067
10+
public event EventHandler<CursorInfo>? OnChange;
11+
#pragma warning restore
12+
13+
14+
public CursorInfo GetCurrentCursor() => new(Array.Empty<byte>(), Point.Empty, "default");
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
using Immense.RemoteControl.Desktop.Shared.Abstractions;
2+
using Immense.RemoteControl.Desktop.Shared.Services;
3+
using Immense.RemoteControl.Desktop.Shared.ViewModels;
4+
using Microsoft.Extensions.Logging;
5+
using System.Collections.Concurrent;
6+
using Immense.RemoteControl.Desktop.UI.Controls.Dialogs;
7+
using Immense.RemoteControl.Desktop.UI.Views;
8+
using Immense.RemoteControl.Desktop.UI.Services;
9+
using System.Threading;
10+
using System.IO;
11+
12+
namespace Immense.RemoteControl.Desktop.Linux.Services;
13+
14+
public class FileTransferServiceLinux : IFileTransferService
15+
{
16+
private static readonly ConcurrentDictionary<string, FileTransferWindow> _fileTransferWindows = new();
17+
private static readonly ConcurrentDictionary<string, FileStream> _partialTransfers = new();
18+
private static readonly SemaphoreSlim _writeLock = new(1, 1);
19+
private static volatile bool _messageBoxPending;
20+
private readonly IViewModelFactory _viewModelFactory;
21+
private readonly IUiDispatcher _dispatcher;
22+
private readonly IDialogProvider _dialogProvider;
23+
private readonly ILogger<FileTransferServiceLinux> _logger;
24+
25+
public FileTransferServiceLinux(
26+
IViewModelFactory viewModelFactory,
27+
IUiDispatcher dispatcher,
28+
IDialogProvider dialogProvider,
29+
ILogger<FileTransferServiceLinux> logger)
30+
{
31+
_viewModelFactory = viewModelFactory;
32+
_dispatcher = dispatcher;
33+
_dialogProvider = dialogProvider;
34+
_logger = logger;
35+
}
36+
37+
public string GetBaseDirectory()
38+
{
39+
var desktopDir = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
40+
if (Directory.Exists(desktopDir))
41+
{
42+
return desktopDir;
43+
}
44+
45+
return Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), "RemoteControl")).FullName;
46+
}
47+
48+
public void OpenFileTransferWindow(IViewer viewer)
49+
{
50+
_dispatcher.Post(() =>
51+
{
52+
if (_fileTransferWindows.TryGetValue(viewer.ViewerConnectionId, out var window))
53+
{
54+
window.Activate();
55+
}
56+
else
57+
{
58+
window = new FileTransferWindow
59+
{
60+
DataContext = _viewModelFactory.CreateFileTransferWindowViewModel(viewer)
61+
};
62+
window.Closed += (sender, arg) =>
63+
{
64+
_fileTransferWindows.Remove(viewer.ViewerConnectionId, out _);
65+
};
66+
_fileTransferWindows.AddOrUpdate(viewer.ViewerConnectionId, window, (k, v) => window);
67+
window.Show();
68+
}
69+
});
70+
}
71+
72+
public async Task ReceiveFile(byte[] buffer, string fileName, string messageId, bool endOfFile, bool startOfFile)
73+
{
74+
try
75+
{
76+
await _writeLock.WaitAsync();
77+
78+
var baseDir = GetBaseDirectory();
79+
80+
if (startOfFile)
81+
{
82+
var filePath = Path.Combine(baseDir, fileName);
83+
84+
if (File.Exists(filePath))
85+
{
86+
var count = 0;
87+
var ext = Path.GetExtension(fileName);
88+
var fileWithoutExt = Path.GetFileNameWithoutExtension(fileName);
89+
while (File.Exists(filePath))
90+
{
91+
filePath = Path.Combine(baseDir, $"{fileWithoutExt}-{count}{ext}");
92+
count++;
93+
}
94+
}
95+
96+
File.Create(filePath).Close();
97+
98+
var fs = new FileStream(filePath, FileMode.OpenOrCreate);
99+
_partialTransfers.AddOrUpdate(messageId, fs, (k, v) => fs);
100+
}
101+
102+
var fileStream = _partialTransfers[messageId];
103+
104+
if (buffer?.Length > 0)
105+
{
106+
await fileStream.WriteAsync(buffer);
107+
108+
}
109+
110+
if (endOfFile)
111+
{
112+
fileStream.Close();
113+
_partialTransfers.Remove(messageId, out _);
114+
}
115+
}
116+
catch (Exception ex)
117+
{
118+
_logger.LogError(ex, "Error while receiving file.");
119+
}
120+
finally
121+
{
122+
_writeLock.Release();
123+
if (endOfFile)
124+
{
125+
await Task.Run(ShowTransferComplete);
126+
}
127+
}
128+
}
129+
130+
public async Task UploadFile(
131+
FileUpload fileUpload,
132+
IViewer viewer,
133+
Action<double> progressUpdateCallback,
134+
CancellationToken cancelToken)
135+
{
136+
try
137+
{
138+
await viewer.SendFile(fileUpload, progressUpdateCallback, cancelToken);
139+
}
140+
catch (Exception ex)
141+
{
142+
_logger.LogError(ex, "Error while uploading file.");
143+
}
144+
}
145+
146+
private async Task ShowTransferComplete()
147+
{
148+
// Prevent multiple dialogs from popping up.
149+
if (!_messageBoxPending)
150+
{
151+
_messageBoxPending = true;
152+
153+
await _dialogProvider.Show($"File tranfer complete. Files saved to directory:\n\n{GetBaseDirectory()}",
154+
"Tranfer Complete",
155+
MessageBoxType.OK);
156+
157+
_messageBoxPending = false;
158+
}
159+
}
160+
}

0 commit comments

Comments
 (0)