public static void Main(string[] args) { try { AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; Conductor = new Conductor(); Conductor.ProcessArgs(args); Conductor.ScreenCastInitiated += ScreenCastInitiated; Conductor.AudioToggled += AudioToggled; Conductor.ClipboardTransferred += Conductor_ClipboardTransferred; Conductor.Connect().ContinueWith(async(task) => { Conductor.SetMessageHandlers(new WinInput()); AudioCapturer = new AudioCapturer(Conductor); CursorIconWatcher = new CursorIconWatcher(Conductor); CursorIconWatcher.OnChange += CursorIconWatcher_OnChange; await Conductor.CasterSocket.SendDeviceInfo(Conductor.ServiceID, Environment.MachineName, Conductor.DeviceID); CheckInitialDesktop(); await CheckForRelaunch(); Conductor.IdleTimer = new IdleTimer(Conductor.Viewers); Conductor.IdleTimer.Start(); await HandleConnection(Conductor); }); Thread.Sleep(Timeout.Infinite); } catch (Exception ex) { Logger.Write(ex); throw; } }
public static void Main(string[] args) { try { AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; Conductor = new Conductor(); Conductor.ProcessArgs(args); Conductor.Connect().Wait(); Conductor.SetMessageHandlers(new WinInput()); Conductor.ScreenCastInitiated += ScreenCastInitiated; AudioCapturer = new AudioCapturer(Conductor); CursorIconWatcher = new CursorIconWatcher(Conductor); CursorIconWatcher.OnChange += CursorIconWatcher_OnChange; Conductor.CasterSocket.SendDeviceInfo(Conductor.ServiceID, Environment.MachineName).Wait(); CheckInitialDesktop(); CheckForRelaunch(); Conductor.StartWaitForViewerTimer(); HandleConnection(Conductor).Wait(); } catch (Exception ex) { Logger.Write(ex); throw; } }
private static void AudioToggled(object sender, bool toggledOn) { if (toggledOn) { AudioCapturer.Start(); } else { AudioCapturer.Stop(); } }
public MainWindowViewModel() { Current = this; Conductor = new Conductor(); Conductor.SessionIDChanged += SessionIDChanged; Conductor.ViewerRemoved += ViewerRemoved; Conductor.ViewerAdded += ViewerAdded; Conductor.ScreenCastRequested += ScreenCastRequested; CursorIconWatcher = new CursorIconWatcher(Conductor); CursorIconWatcher.OnChange += CursorIconWatcher_OnChange; AudioCapturer = new AudioCapturer(Conductor); }
private void ScreenCastRequested(object sender, ScreenCastRequest screenCastRequest) { App.Current.Dispatcher.Invoke(() => { var result = MessageBox.Show($"You've received a connection request from {screenCastRequest.RequesterName}. Accept?", "Connection Request", MessageBoxButton.YesNo, MessageBoxImage.Question); if (result == MessageBoxResult.Yes) { Task.Run(async() => { ICapturer capturer; try { if (Conductor.Viewers.Count == 0) { capturer = new DXCapture(); } else { capturer = new BitBltCapture(); } } catch (Exception ex) { Logger.Write(ex); capturer = new BitBltCapture(); } await Conductor.CasterSocket.SendCursorChange(CursorIconWatcher.GetCurrentCursor(), new List <string>() { screenCastRequest.ViewerID }); ScreenCaster.BeginScreenCasting(screenCastRequest.ViewerID, screenCastRequest.RequesterName, capturer, Conductor); AudioCapturer.Start(); }); } }); }
private void ToggleAudio(byte[] message) { var dto = MessagePackSerializer.Deserialize <ToggleAudioDto>(message); AudioCapturer.ToggleAudio(dto.ToggleOn); }
private void ApplyConnectionHandlers() { // TODO: Remove circular dependencies and the need for static IServiceProvider instance // by emitting these events so other services can listen for them. var conductor = ServiceContainer.Instance.GetRequiredService <Conductor>(); Connection.Closed += (ex) => { Logger.Write($"Connection closed. Error: {ex?.Message}"); return(Task.CompletedTask); }; Connection.On("ReceiveIceCandidate", (string candidate, int sdpMlineIndex, string sdpMid, string viewerID) => { try { if (conductor.Viewers.TryGetValue(viewerID, out var viewer)) { viewer.RtcSession.AddIceCandidate(sdpMid, sdpMlineIndex, candidate); } } catch (Exception ex) { Logger.Write(ex); } }); Connection.On("ReceiveRtcAnswer", async(string sdp, string viewerID) => { try { if (conductor.Viewers.TryGetValue(viewerID, out var viewer)) { await viewer.RtcSession.SetRemoteDescription("answer", sdp); } } catch (Exception ex) { Logger.Write(ex); } }); Connection.On("ClipboardTransfer", (string transferText, bool typeText, string viewerID) => { try { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { if (typeText) { KeyboardMouseInput.SendText(transferText, viewer); } else { ClipboardService.SetText(transferText); } } } catch (Exception ex) { Logger.Write(ex); } }); Connection.On("CtrlAltDel", async(string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { await SendCtrlAltDel(); } }); Connection.On("Disconnect", async(string reason) => { Logger.Write($"Disconnecting caster socket. Reason: {reason}"); await DisconnectAllViewers(); }); Connection.On("GetScreenCast", (string viewerID, string requesterName, bool notifyUser) => { try { ScreenCaster.BeginScreenCasting(new ScreenCastRequest() { NotifyUser = notifyUser, ViewerID = viewerID, RequesterName = requesterName }); } catch (Exception ex) { Logger.Write(ex); } }); Connection.On("GetWindowsSessions", async(string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer)) { await viewer.SendWindowsSessions(); } }); Connection.On("RequestScreenCast", (string viewerID, string requesterName, bool notifyUser) => { conductor.InvokeScreenCastRequested(new ScreenCastRequest() { NotifyUser = notifyUser, ViewerID = viewerID, RequesterName = requesterName }); }); Connection.On("KeyDown", (string key, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { KeyboardMouseInput.SendKeyDown(key, viewer); } }); Connection.On("KeyUp", (string key, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { KeyboardMouseInput.SendKeyUp(key, viewer); } }); Connection.On("KeyPress", async(string key, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { KeyboardMouseInput.SendKeyDown(key, viewer); await Task.Delay(1); KeyboardMouseInput.SendKeyUp(key, viewer); } }); Connection.On("MouseMove", (double percentX, double percentY, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { KeyboardMouseInput.SendMouseMove(percentX, percentY, viewer); } }); Connection.On("MouseDown", (int button, double percentX, double percentY, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { if (button == 0) { KeyboardMouseInput.SendLeftMouseDown(percentX, percentY, viewer); } else if (button == 2) { KeyboardMouseInput.SendRightMouseDown(percentX, percentY, viewer); } } }); Connection.On("MouseUp", (int button, double percentX, double percentY, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { if (button == 0) { KeyboardMouseInput.SendLeftMouseUp(percentX, percentY, viewer); } else if (button == 2) { KeyboardMouseInput.SendRightMouseUp(percentX, percentY, viewer); } } }); Connection.On("MouseWheel", (double deltaX, double deltaY, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { KeyboardMouseInput.SendMouseWheel(-(int)deltaY, viewer); } }); Connection.On("SetKeyStatesUp", (string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { KeyboardMouseInput.SetKeyStatesUp(); } }); Connection.On("ViewerDisconnected", async(string viewerID) => { await Connection.SendAsync("DisconnectViewer", viewerID, false); if (conductor.Viewers.TryGetValue(viewerID, out var viewer)) { viewer.DisconnectRequested = true; viewer.Dispose(); } conductor.InvokeViewerRemoved(viewerID); }); Connection.On("FrameReceived", (string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer)) { for (int i = 0; i < 5; i++) { if (viewer.PendingSentFrames.TryDequeue(out _)) { break; } } } }); Connection.On("SelectScreen", (string displayName, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer)) { viewer.Capturer.SetSelectedScreen(displayName); } }); Connection.On("QualityChange", (int qualityLevel, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer)) { viewer.ImageQuality = qualityLevel; } }); Connection.On("AutoQualityAdjust", (bool isOn, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer)) { viewer.AutoAdjustQuality = isOn; } }); Connection.On("ReceiveFile", async(byte[] buffer, string fileName, string messageId, bool endOfFile, bool startOfFile) => { await FileDownloadService.ReceiveFile(buffer, fileName, messageId, endOfFile, startOfFile); }); Connection.On("ToggleAudio", (bool toggleOn, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { AudioCapturer.ToggleAudio(toggleOn); } }); Connection.On("ToggleBlockInput", (bool toggleOn, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { KeyboardMouseInput.ToggleBlockInput(toggleOn); } }); Connection.On("ToggleWebRtcVideo", (bool toggleOn, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer)) { viewer.ToggleWebRtcVideo(toggleOn); } }); Connection.On("TouchDown", (string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { //User32.GetCursorPos(out var point); //Win32Interop.SendLeftMouseDown(point.X, point.Y); } }); Connection.On("LongPress", (string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { //User32.GetCursorPos(out var point); //Win32Interop.SendRightMouseDown(point.X, point.Y); //Win32Interop.SendRightMouseUp(point.X, point.Y); } }); Connection.On("TouchMove", (double moveX, double moveY, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { //User32.GetCursorPos(out var point); //Win32Interop.SendMouseMove(point.X + moveX, point.Y + moveY); } }); Connection.On("TouchUp", (string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { //User32.GetCursorPos(out var point); //Win32Interop.SendLeftMouseUp(point.X, point.Y); } }); Connection.On("Tap", (double percentX, double percentY, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { KeyboardMouseInput.SendLeftMouseDown(percentX, percentY, viewer); KeyboardMouseInput.SendLeftMouseUp(percentX, percentY, viewer); } }); Connection.On("SharedFileIDs", (List <string> fileIDs) => { fileIDs.ForEach(id => { var url = $"{conductor.Host}/API/FileSharing/{id}"; var webRequest = WebRequest.CreateHttp(url); var response = webRequest.GetResponse(); var contentDisp = response.Headers["Content-Disposition"]; var fileName = contentDisp .Split(";".ToCharArray()) .FirstOrDefault(x => x.Trim().StartsWith("filename")) .Split("=".ToCharArray())[1]; var legalChars = fileName.ToCharArray().Where(x => !Path.GetInvalidFileNameChars().Any(y => x == y)); fileName = new string(legalChars.ToArray()); var dirPath = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), "RemotelySharedFiles")).FullName; var filePath = Path.Combine(dirPath, fileName); using (var fs = new FileStream(filePath, FileMode.Create)) { using (var rs = response.GetResponseStream()) { rs.CopyTo(fs); } } Process.Start("explorer.exe", dirPath); }); }); Connection.On("SessionID", (string sessionID) => { conductor.InvokeSessionIDChanged(sessionID); }); }
private void ApplyConnectionHandlers() { var conductor = ServiceContainer.Instance.GetRequiredService <Conductor>(); Connection.Closed += (ex) => { Logger.Write($"Connection closed. Error: {ex?.Message}"); return(Task.CompletedTask); }; Connection.On("ReceiveIceCandidate", (string candidate, int sdpMlineIndex, string sdpMid, string viewerID) => { try { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { viewer.RtcSession.AddIceCandidate(sdpMid, sdpMlineIndex, candidate); } } catch (Exception ex) { Logger.Write(ex); } }); Connection.On("ReceiveRtcAnswer", (string sdp, string viewerID) => { try { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { viewer.RtcSession.SetRemoteDescription("answer", sdp); } } catch (Exception ex) { Logger.Write(ex); } }); Connection.On("ClipboardTransfer", (string transferText, bool typeText, string viewerID) => { try { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { if (typeText) { KeyboardMouseInput.SendText(transferText, viewer); } else { ClipboardService.SetText(transferText); } } } catch (Exception ex) { Logger.Write(ex); } }); Connection.On("CtrlAltDel", async(string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { await Connection.InvokeAsync("CtrlAltDel"); } }); Connection.On("Disconnect", async(string reason) => { Logger.Write($"Disconnecting caster socket. Reason: {reason}"); foreach (var viewer in conductor.Viewers.Values.ToList()) { await Connection.InvokeAsync("ViewerDisconnected", viewer.ViewerConnectionID); viewer.DisconnectRequested = true; } }); Connection.On("GetScreenCast", (string viewerID, string requesterName) => { try { ScreenCaster.BeginScreenCasting(new ScreenCastRequest() { ViewerID = viewerID, RequesterName = requesterName }); } catch (Exception ex) { Logger.Write(ex); } }); Connection.On("RequestScreenCast", (string viewerID, string requesterName) => { conductor.InvokeScreenCastRequested(new ScreenCastRequest() { ViewerID = viewerID, RequesterName = requesterName }); }); Connection.On("KeyDown", (string key, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { KeyboardMouseInput.SendKeyDown(key, viewer); } }); Connection.On("KeyUp", (string key, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { KeyboardMouseInput.SendKeyUp(key, viewer); } }); Connection.On("KeyPress", async(string key, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { KeyboardMouseInput.SendKeyDown(key, viewer); await Task.Delay(1); KeyboardMouseInput.SendKeyUp(key, viewer); } }); Connection.On("MouseMove", (double percentX, double percentY, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { KeyboardMouseInput.SendMouseMove(percentX, percentY, viewer); } }); Connection.On("MouseDown", (int button, double percentX, double percentY, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { if (button == 0) { KeyboardMouseInput.SendLeftMouseDown(percentX, percentY, viewer); } else if (button == 2) { KeyboardMouseInput.SendRightMouseDown(percentX, percentY, viewer); } } }); Connection.On("MouseUp", (int button, double percentX, double percentY, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { if (button == 0) { KeyboardMouseInput.SendLeftMouseUp(percentX, percentY, viewer); } else if (button == 2) { KeyboardMouseInput.SendRightMouseUp(percentX, percentY, viewer); } } }); Connection.On("MouseWheel", (double deltaX, double deltaY, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { KeyboardMouseInput.SendMouseWheel(-(int)deltaY, viewer); } }); Connection.On("ViewerDisconnected", async(string viewerID) => { await Connection.InvokeAsync("ViewerDisconnected", viewerID); if (conductor.Viewers.TryGetValue(viewerID, out var viewer)) { viewer.DisconnectRequested = true; } conductor.InvokeViewerRemoved(viewerID); }); Connection.On("LatencyUpdate", (DateTime sentTime, int bytesReceived, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer)) { var latency = DateTime.UtcNow - sentTime; viewer.Latency = latency.TotalMilliseconds; viewer.WebSocketBuffer = Math.Max(0, viewer.WebSocketBuffer - bytesReceived); } }); Connection.On("SelectScreen", (int screenIndex, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer)) { viewer.Capturer.SetSelectedScreen(screenIndex); } }); Connection.On("QualityChange", (int qualityLevel, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer)) { viewer.ImageQuality = qualityLevel; } }); Connection.On("AutoQualityAdjust", (bool isOn, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer)) { viewer.AutoAdjustQuality = isOn; } }); Connection.On("ToggleAudio", (bool toggleOn, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { AudioCapturer.ToggleAudio(toggleOn); } }); Connection.On("ToggleBlockInput", (bool toggleOn, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { KeyboardMouseInput.ToggleBlockInput(toggleOn); } }); Connection.On("TouchDown", (string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { //User32.GetCursorPos(out var point); //Win32Interop.SendLeftMouseDown(point.X, point.Y); } }); Connection.On("LongPress", (string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { //User32.GetCursorPos(out var point); //Win32Interop.SendRightMouseDown(point.X, point.Y); //Win32Interop.SendRightMouseUp(point.X, point.Y); } }); Connection.On("TouchMove", (double moveX, double moveY, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { //User32.GetCursorPos(out var point); //Win32Interop.SendMouseMove(point.X + moveX, point.Y + moveY); } }); Connection.On("TouchUp", (string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { //User32.GetCursorPos(out var point); //Win32Interop.SendLeftMouseUp(point.X, point.Y); } }); Connection.On("Tap", (double percentX, double percentY, string viewerID) => { if (conductor.Viewers.TryGetValue(viewerID, out var viewer) && viewer.HasControl) { KeyboardMouseInput.SendLeftMouseDown(percentX, percentY, viewer); KeyboardMouseInput.SendLeftMouseUp(percentX, percentY, viewer); } }); Connection.On("SharedFileIDs", (List <string> fileIDs) => { fileIDs.ForEach(id => { var url = $"{conductor.Host}/API/FileSharing/{id}"; var webRequest = WebRequest.CreateHttp(url); var response = webRequest.GetResponse(); var contentDisp = response.Headers["Content-Disposition"]; var fileName = contentDisp .Split(";".ToCharArray()) .FirstOrDefault(x => x.Trim().StartsWith("filename")) .Split("=".ToCharArray())[1]; var legalChars = fileName.ToCharArray().Where(x => !Path.GetInvalidFileNameChars().Any(y => x == y)); fileName = new string(legalChars.ToArray()); var dirPath = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), "RemotelySharedFiles")).FullName; var filePath = Path.Combine(dirPath, fileName); using (var fs = new FileStream(filePath, FileMode.Create)) { using (var rs = response.GetResponseStream()) { rs.CopyTo(fs); } } Process.Start("explorer.exe", dirPath); }); }); Connection.On("SessionID", (string sessionID) => { conductor.InvokeSessionIDChanged(sessionID); }); }
protected override void OnStartup(StartupEventArgs e) { AudioCapturer.Init(); base.OnStartup(e); }