diff --git a/Remotely_Agent/Services/DeviceSocket.cs b/Remotely_Agent/Services/DeviceSocket.cs index 619963af..2730832d 100644 --- a/Remotely_Agent/Services/DeviceSocket.cs +++ b/Remotely_Agent/Services/DeviceSocket.cs @@ -275,12 +275,11 @@ namespace Remotely_Agent.Services if (Program.IsDebug) { - Process.Start(filePath, $"-mode unattended -requester {requesterID} -serviceid {serviceID} -host {Utilities.GetConnectionInfo().Host}"); + Process.Start(filePath, $"-mode Unattended -requester {requesterID} -serviceid {serviceID} -host {Utilities.GetConnectionInfo().Host} -desktop default"); } else { - var procInfo = new ADVAPI32.PROCESS_INFORMATION(); - var result = Win32Interop.OpenInteractiveProcess(filePath + $" -mode unattended -requester {requesterID} -serviceid {serviceID} -host {Utilities.GetConnectionInfo().Host}", "default", true, out procInfo); + var result = Win32Interop.OpenInteractiveProcess(filePath + $" -mode Unattended -requester {requesterID} -serviceid {serviceID} -host {Utilities.GetConnectionInfo().Host}", "default", true, out _); if (!result) { await hubConnection.InvokeAsync("DisplayConsoleMessage", "Remote control failed to start on target device.", requesterID); @@ -293,7 +292,7 @@ namespace Remotely_Agent.Services // var users = OSUtils.StartProcessWithResults("users", ""); // var username = users?.Split()?.FirstOrDefault()?.Trim(); - // Process.Start("sudo", $"-u {username} {rcBinaryPath} -mode unattended -requester {requesterID} -serviceid {serviceID} -desktop default -hostname {Utilities.GetConnectionInfo().Host.Split("//").Last()}"); + // Process.Start("sudo", $"-u {username} {rcBinaryPath} -mode Unattended -requester {requesterID} -serviceid {serviceID} -desktop default -hostname {Utilities.GetConnectionInfo().Host.Split("//").Last()}"); //} } catch diff --git a/Remotely_ScreenCast/Capture/BitBltCapture.cs b/Remotely_ScreenCast/Capture/BitBltCapture.cs index 13c3d399..0462305c 100644 --- a/Remotely_ScreenCast/Capture/BitBltCapture.cs +++ b/Remotely_ScreenCast/Capture/BitBltCapture.cs @@ -80,16 +80,6 @@ namespace Remotely_ScreenCast.Capture public void Capture() { - var currentDesktop = Win32Interop.GetCurrentDesktop(); - if (currentDesktop != desktopName) - { - desktopName = currentDesktop; - var inputDesktop = Win32Interop.OpenInputDesktop(); - var success = User32.SetThreadDesktop(inputDesktop); - User32.CloseDesktop(inputDesktop); - Logger.Write($"Set thread desktop to {currentDesktop}: {success}"); - } - // Keep framerate below 30 FPS. if (FramerateTimer.Elapsed.TotalMilliseconds > 33) { @@ -122,14 +112,14 @@ namespace Remotely_ScreenCast.Capture } finally { - if (graphDC != IntPtr.Zero) - { - graphic.ReleaseHdc(graphDC); - } - if (hDC != IntPtr.Zero) - { - User32.ReleaseDC(hWnd, hDC); - } + //if (graphDC != IntPtr.Zero) + //{ + // graphic.ReleaseHdc(graphDC); + //} + //if (hDC != IntPtr.Zero) + //{ + // User32.ReleaseDC(hWnd, hDC); + //} } } } diff --git a/Remotely_ScreenCast/Capture/ScreenCaster.cs b/Remotely_ScreenCast/Capture/ScreenCaster.cs index fb3c8e93..5e97df78 100644 --- a/Remotely_ScreenCast/Capture/ScreenCaster.cs +++ b/Remotely_ScreenCast/Capture/ScreenCaster.cs @@ -19,36 +19,28 @@ namespace Remotely_ScreenCast.Capture string requesterName, OutgoingMessages outgoingMessages) { - var inputDesktop = Win32Interop.OpenInputDesktop(); - var result = User32.SetThreadDesktop(inputDesktop); - User32.CloseDesktop(inputDesktop); - Logger.Write($"Set thread desktop begin screencasting to {Win32Interop.GetCurrentDesktop()}: {result}"); - - ICapturer capturer; CaptureMode captureMode; - capturer = new BitBltCapture(); - captureMode = CaptureMode.BitBtl; - //try - //{ - // if (Program.Viewers.Count == 0) - // { - // capturer = new DXCapture(); - // captureMode = CaptureMode.DirectX; - // } - // else - // { - // capturer = new BitBltCapture(); - // captureMode = CaptureMode.BitBtl; - // } - //} - //catch (Exception ex) - //{ - // Logger.Write(ex); - // capturer = new BitBltCapture(); - // captureMode = CaptureMode.BitBtl; - //} + try + { + if (Program.Viewers.Count == 0) + { + capturer = new DXCapture(); + captureMode = CaptureMode.DirectX; + } + else + { + capturer = new BitBltCapture(); + captureMode = CaptureMode.BitBtl; + } + } + catch (Exception ex) + { + Logger.Write(ex); + capturer = new BitBltCapture(); + captureMode = CaptureMode.BitBtl; + } Logger.Write($"Starting screen cast. Requester: {requesterName}. Viewer ID: {viewerID}. Capture Mode: {captureMode.ToString()}. Desktop: {Win32Interop.GetCurrentDesktop()}"); @@ -59,7 +51,7 @@ namespace Remotely_ScreenCast.Capture DisconnectRequested = false, Name = requesterName, ViewerConnectionID = viewerID, - HasControl = Program.Mode == "unattended" + HasControl = Program.Mode == Enums.AppMode.Unattended }; @@ -109,13 +101,19 @@ namespace Remotely_ScreenCast.Capture Logger.Write(ex); } } - + Logger.Write($"Ended screen cast. Requester: {requesterName}. Viewer ID: {viewerID}."); success = false; while (!success) { - Program.Viewers.TryRemove(viewerID, out _); + success = Program.Viewers.TryRemove(viewerID, out _); } - Logger.Write($"Ended screen cast. Requester: {requesterName}. Viewer ID: {viewerID}."); + + // Close if no one is viewing. + if (Program.Viewers.Count == 0) + { + Environment.Exit(0); + } + } public static Tuple GetAbsolutePercentFromRelativePercent(double percentX, double percentY, ICapturer capturer) { diff --git a/Remotely_ScreenCast/Enums/AppMode.cs b/Remotely_ScreenCast/Enums/AppMode.cs new file mode 100644 index 00000000..13ea2999 --- /dev/null +++ b/Remotely_ScreenCast/Enums/AppMode.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Remotely_ScreenCast.Enums +{ + public enum AppMode + { + Unattended, + Normal + } +} diff --git a/Remotely_ScreenCast/Program.cs b/Remotely_ScreenCast/Program.cs index d680d325..a23c75aa 100644 --- a/Remotely_ScreenCast/Program.cs +++ b/Remotely_ScreenCast/Program.cs @@ -1,6 +1,7 @@ using Microsoft.AspNetCore.SignalR.Client; using Remotely_ScreenCast; using Remotely_ScreenCast.Capture; +using Remotely_ScreenCast.Enums; using Remotely_ScreenCast.Models; using Remotely_ScreenCast.Sockets; using Remotely_ScreenCast.Utilities; @@ -24,7 +25,7 @@ namespace Remotely_ScreenCast public static ICapturer Capturer { get; private set; } public static CaptureMode CaptureMode { get; private set; } public static bool DisconnectRequested { get; set; } - public static string Mode { get; private set; } + public static AppMode Mode { get; private set; } public static string RequesterID { get; private set; } public static string ServiceID { get; private set; } public static string Host { get; private set; } @@ -38,17 +39,13 @@ namespace Remotely_ScreenCast try { AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; - - var inputDesktop = Win32Interop.OpenInputDesktop(); - var success = User32.SetThreadDesktop(inputDesktop); - User32.CloseDesktop(inputDesktop); - CurrentDesktopName = Win32Interop.GetCurrentDesktop(); - Logger.Write($"Set thread desktop on launch to {CurrentDesktopName}: {success}"); var argDict = ProcessArgs(args); - Mode = argDict["mode"]; + Mode = (AppMode)Enum.Parse(typeof(AppMode), argDict["mode"]); RequesterID = argDict["requester"]; Host = argDict["host"]; + CurrentDesktopName = argDict["desktop"]; + ServiceID = argDict["serviceid"]; Connection = new HubConnectionBuilder() .WithUrl($"{Host}/RCDeviceHub") @@ -56,26 +53,37 @@ namespace Remotely_ScreenCast Connection.StartAsync().Wait(); + if (Win32Interop.GetCurrentDesktop().ToLower() != CurrentDesktopName.ToLower()) + { + RelaunchInCurrentDesktop().Wait(); + } + OutgoingMessages = new OutgoingMessages(Connection); MessageHandlers.ApplyConnectionHandlers(Connection, OutgoingMessages); CursorIconWatcher.Current.OnChange += CursorIconWatcher_OnChange; - OutgoingMessages.NotifyRequesterUnattendedReady(RequesterID).Wait(); + if (argDict.ContainsKey("desktopswitch")) + { + var viewersString = argDict["viewers"]; + var viewerIDs = viewersString.Split(",".ToCharArray()); + // TODO. + } + else + { + OutgoingMessages.NotifyRequesterUnattendedReady(RequesterID).Wait(); + } StartWaitForViewerTimer(); while (true) { var desktopName = Win32Interop.GetCurrentDesktop(); - if (desktopName != CurrentDesktopName) + if (desktopName.ToLower() != CurrentDesktopName.ToLower()) { - CurrentDesktopName = desktopName; - inputDesktop = Win32Interop.OpenInputDesktop(); - success = User32.SetThreadDesktop(inputDesktop); - User32.CloseDesktop(inputDesktop); - Logger.Write($"Set thread desktop on main thread to {CurrentDesktopName}: {success}"); + SwitchDesktops(desktopName).Wait(); + Environment.Exit(0); } System.Threading.Thread.Sleep(100); } @@ -86,6 +94,29 @@ namespace Remotely_ScreenCast } } + private static async Task RelaunchInCurrentDesktop() + { + var result = Win32Interop.OpenInteractiveProcess(Environment.CommandLine, Win32Interop.GetCurrentDesktop(), true, out _); + if (!result) + { + // TODO. + //await Connection.InvokeAsync("DisplayMessage", "Remote control failed to start on target device.", RequesterID); + } + await Task.Delay(1); + } + + private static async Task SwitchDesktops(string desktopName) + { + Logger.Write($"Switching desktops to {desktopName}."); + await Connection.InvokeAsync("SwitchDesktops"); + var result = Win32Interop.OpenInteractiveProcess(Assembly.GetExecutingAssembly().Location + $" -mode {Mode.ToString()} -requester {RequesterID} -serviceid {ServiceID} -host {Host} -desktopswitch true -desktop {desktopName} -viewers {String.Join(",", Viewers.Keys.ToList())}", desktopName, true, out _); + if (!result) + { + // TODO. + //await Connection.InvokeAsync("DisplayMessage", "Desktop switch failed on target device.", RequesterID); + } + } + private static async void CursorIconWatcher_OnChange(object sender, int cursor) { await OutgoingMessages.SendCursorChange(cursor, Viewers.Keys.ToList()); diff --git a/Remotely_ScreenCast/Remotely_ScreenCast.csproj b/Remotely_ScreenCast/Remotely_ScreenCast.csproj index aea169b1..e0c721bb 100644 --- a/Remotely_ScreenCast/Remotely_ScreenCast.csproj +++ b/Remotely_ScreenCast/Remotely_ScreenCast.csproj @@ -147,6 +147,7 @@ + diff --git a/Remotely_ScreenCast/Sockets/MessageHandlers.cs b/Remotely_ScreenCast/Sockets/MessageHandlers.cs index dd2afa7b..9c1a33e5 100644 --- a/Remotely_ScreenCast/Sockets/MessageHandlers.cs +++ b/Remotely_ScreenCast/Sockets/MessageHandlers.cs @@ -120,17 +120,6 @@ namespace Remotely_ScreenCast.Sockets if (Program.Viewers.TryGetValue(viewerID, out var viewer)) { viewer.DisconnectRequested = true; - var success = false; - while (!success) - { - success = Program.Viewers.TryRemove(viewerID, out _); - } - - // Close if no one is viewing. - if (Program.Viewers.Count == 0) - { - Environment.Exit(0); - } } await hubConnection.InvokeAsync("ViewerDisconnected", viewerID); }); diff --git a/Remotely_Server/Services/RCBrowserSocketHub.cs b/Remotely_Server/Services/RCBrowserSocketHub.cs index 2a77915d..6d79f4ce 100644 --- a/Remotely_Server/Services/RCBrowserSocketHub.cs +++ b/Remotely_Server/Services/RCBrowserSocketHub.cs @@ -27,6 +27,10 @@ namespace Remotely_Server.Services { return Context.Items["ClientID"] as string; } + set + { + Context.Items["ClientID"] = value; + } } private string ClientType @@ -146,6 +150,10 @@ namespace Remotely_Server.Services Context.Items["RequesterName"] = requesterName; await RCDeviceHub.Clients.Client(clientID).SendAsync("GetScreenCast", Context.ConnectionId, requesterName); } + public void SwitchDesktops(string newClientID) + { + ClientID = newClientID; + } public async Task SendFrameSkip(int delayTime) { await RCDeviceHub.Clients.Client(ClientID).SendAsync("FrameSkip", delayTime, Context.ConnectionId); diff --git a/Remotely_Server/Services/RCDeviceSocketHub.cs b/Remotely_Server/Services/RCDeviceSocketHub.cs index 8e00b4b0..9ef08141 100644 --- a/Remotely_Server/Services/RCDeviceSocketHub.cs +++ b/Remotely_Server/Services/RCDeviceSocketHub.cs @@ -32,6 +32,21 @@ namespace Remotely_Server.Services private DataService DataService { get; } private IHubContext BrowserHub { get; } private IHubContext RCBrowserHub { get; } + private bool IsSwitchingDesktops + { + get + { + if (!Context.Items.ContainsKey("IsSwitchingDesktops")) + { + Context.Items["IsSwitchingDesktops"] = false; + } + return (bool)Context.Items["IsSwitchingDesktops"]; + } + set + { + Context.Items["IsSwitchingDesktops"] = value; + } + } private List ViewerList { get @@ -52,7 +67,10 @@ namespace Remotely_Server.Services } public override async Task OnDisconnectedAsync(Exception exception) { - await RCBrowserHub.Clients.Clients(ViewerList).SendAsync("ScreenCasterDisconnected"); + if (!IsSwitchingDesktops) + { + await RCBrowserHub.Clients.Clients(ViewerList).SendAsync("ScreenCasterDisconnected"); + } if (Context.Items.ContainsKey("SessionID") && AttendedSessionList.ContainsKey(Context.Items["SessionID"].ToString())) { while (!AttendedSessionList.TryRemove(Context.Items["SessionID"].ToString(), out var value)) @@ -103,6 +121,10 @@ namespace Remotely_Server.Services await RCBrowserHub.Clients.Clients(viewerIDs).SendAsync("CursorChange", cursor); } + public void SwitchDesktops() + { + IsSwitchingDesktops = true; + } public async Task GetSessionID() {