private async Task InitializeRemoteComponents(CaptureType captureType, ImageCompressionType compressionType)
        {
            await ConnectionInfo.SendCommand(this, new[]
            {
                (byte)RemoteDesktopCommunication.Initialize, (byte)captureType, (byte)CurrentScreen.Number,
                (byte)ImageQuality, ShowCursor ? (byte)1 : (byte)0, (byte)compressionType
            });

            /*ConnectionInfo.Sender.UnsafeSendCommand(ConnectionInfo.ClientInformation.Id, Identifier,
             *  new WriterCall(new[]
             *  {
             *      (byte) RemoteDesktopCommunication.Initialize, (byte) captureType, (byte) CurrentScreen.Number,
             *      (byte) ImageQuality, ShowCursor ? (byte) 1 : (byte) 0, (byte) compressionType
             *  }));*/
            // ConnectionInfo.UnsafeSendCommand(this, new WriterCall(new[]
            //  {
            //     (byte) RemoteDesktopCommunication.Initialize, (byte) captureType, (byte) CurrentScreen.Number,
            //      (byte) ImageQuality, ShowCursor ? (byte) 1 : (byte) 0, (byte) compressionType
            // }));

            CaptureType = captureType;

            _currentlyStreamedMonitor = CurrentScreen.Number;

            _streamCodec?.Dispose();
            _cursorStreamCodec?.Dispose();

            _streamCodec = new UnsafeStreamCodec(GetImageCompression(compressionType),
                                                 UnsafeStreamCodecParameters.DontDisposeImageCompressor);
            _cursorStreamCodec = new CursorStreamCodec();
        }
Exemple #2
0
        private void InitializeStreamingComponents(CaptureType captureType, int monitor, int quality,
                                                   IConnectionInfo connectionInfo, bool drawCursor, ImageCompressionType compressionType)
        {
            var oldScreenCaptureService = _screenCaptureService;

            _screenCaptureService = _screenCaptureServices[captureType]();

            try
            {
                _screenCaptureService.Initialize(monitor);
            }
            catch (Exception ex)
            {
                _screenCaptureService = oldScreenCaptureService;
                ResponseBytes((byte)RemoteDesktopCommunication.ResponseInitializationFailed,
                              Encoding.UTF8.GetBytes(ex.Message), connectionInfo);
                return;
            }

            Program.WriteLine($"InitializeStreamingComponents: oldScreenCaptureService == null: {oldScreenCaptureService == null} (else dispose)");

            oldScreenCaptureService?.Dispose();

            Program.WriteLine("Dispose other stuff in InitializeStreamingComponents");

            _unsafeCodec?.Dispose();
            _cursorStreamCodec?.Dispose();

            _unsafeCodec = new UnsafeStreamCodec(GetImageCompression(compressionType),
                                                 UnsafeStreamCodecParameters.DontDisposeImageCompressor |
                                                 UnsafeStreamCodecParameters.UpdateImageEveryTwoSeconds);

            _currentImageCompression.Quality = quality;

            if (drawCursor)
            {
                _cursorStreamCodec = new CursorStreamCodec();
            }

            _compressionType = compressionType;

            _currentMonitor = monitor;
            _drawCursor     = drawCursor;

            ResponseByte((byte)RemoteDesktopCommunication.ResponseInitializationSucceeded, connectionInfo);
            Debug.Print("Initialized");
        }
        private async Task Stop(bool remoteCancelled)
        {
            if (!IsStreaming)
            {
                return;
            }

            if (!remoteCancelled)
            {
                await ConnectionInfo.SendCommand(this, (byte)RemoteDesktopCommunication.Stop);
            }

            //important, else dead lock because this is UI thread and lock invokdes into UI thread -> block
            await Task.Run(() =>
            {
                lock (_updateLock)
                {
                    IsStreaming = false;
                }
            });

            FramesPerSecond = 0;
            _framesReceived = 0;

            _cursorStreamCodec?.Dispose();
            _streamCodec?.Dispose();
            _currentImageCompression?.Dispose();
            _remoteConnection?.Dispose();

            _remoteConnection        = null;
            _currentImageCompression = null;
            _cursorStreamCodec       = null;
            _streamCodec             = null;

            LogService.Send((string)Application.Current.Resources["StopRemoteDesktop"]);
        }
Exemple #4
0
        public override void ProcessCommand(byte[] parameter, IConnectionInfo connectionInfo)
        {
            Program.WriteLine("Remote Desktop command received: " + (RemoteDesktopCommunication)parameter[0]);

            switch ((RemoteDesktopCommunication)parameter[0])
            {
            case RemoteDesktopCommunication.GetInfo:
                var remoteDesktopInformation = new RemoteDesktopInformation
                {
                    Screens = new List <ScreenInfo>()
                };

                var screens  = Screen.AllScreens;
                var allNames = ScreenExtensions.GetAllMonitorsFriendlyNames().ToArray();

                for (int i = 0; i < screens.Length; i++)
                {
                    remoteDesktopInformation.Screens.Add(new ScreenInfo
                    {
                        Number = i,
                        Width  = screens[i].Bounds.Width,
                        Height = screens[i].Bounds.Height,
                        Name   =
                            allNames.Length >= i && !string.IsNullOrEmpty(allNames[i])
                                    ? allNames[i]
                                    : screens[i].DeviceName
                    });
                }

                foreach (var screenCaptureService in _screenCaptureServices)
                {
                    if (screenCaptureService.Value().IsSupported)
                    {
                        remoteDesktopInformation.AvailableCaptureTypes |= screenCaptureService.Key;
                    }
                }

                ResponseBytes((byte)RemoteDesktopCommunication.ResponseInfo,
                              new Serializer(typeof(RemoteDesktopInformation)).Serialize(remoteDesktopInformation),
                              connectionInfo);
                break;

            case RemoteDesktopCommunication.InitializeConnection:
                var connectionGuid = new Guid(parameter.Skip(1).Take(16).ToArray());
                _connection?.Dispose();
                _connection = connectionInfo.ConnectionInitializer.TakeConnection(connectionGuid);
                break;

            case RemoteDesktopCommunication.InitializeDirectConnection:
                _connection = new ServerConnection(connectionInfo, this,
                                                   (byte)RemoteDesktopCommunication.ResponseFrame);
                break;

            case RemoteDesktopCommunication.Initialize:
                var captureType = (CaptureType)parameter[1];
                var monitor     = (int)parameter[2];
                var quality     = (int)parameter[3];
                var drawCursor  = parameter[4] == 1;
                var compression = (ImageCompressionType)parameter[5];

                Program.WriteLine("Lock _streamComponents, InitializeStreamingComponents");

                lock (_streamComponentsLock)
                    InitializeStreamingComponents(captureType, monitor, quality, connectionInfo, drawCursor, compression);
                break;

            case RemoteDesktopCommunication.ChangeQuality:
                var newQuality = (int)parameter[1];

                lock (_streamComponentsLock)
                {
                    if (_unsafeCodec.ImageQuality != newQuality)
                    {
                        _unsafeCodec.ImageQuality = newQuality;
                    }
                }
                break;

            case RemoteDesktopCommunication.Start:
                if (_isStreaming)
                {
                    return;
                }

                Program.WriteLine("Start streaming; _isStreaming = true");

                _connectionInfo = connectionInfo;
                _isStreaming    = true;
                new Thread(Streaming)
                {
                    IsBackground = true
                }.Start();
                break;

            case RemoteDesktopCommunication.Stop:
                Program.WriteLine("Stop streaming...; _isStreaming = false; Lock _streamComponentsLock");

                _isStreaming = false;
                //important, it locks this command until the stuff is stopped
                lock (_streamComponentsLock) { }

                Program.WriteLine("Stopped streaming");
                break;

            case RemoteDesktopCommunication.ChangeMonitor:
                monitor = parameter[1];
                lock (_streamComponentsLock)
                {
                    _screenCaptureService.ChangeMonitor(monitor);
                    _unsafeCodec?.Dispose();

                    _unsafeCodec = new UnsafeStreamCodec(GetImageCompression(_compressionType),
                                                         UnsafeStreamCodecParameters.UpdateImageEveryTwoSeconds |
                                                         UnsafeStreamCodecParameters.DontDisposeImageCompressor);

                    _currentMonitor = monitor;
                }
                break;

            case RemoteDesktopCommunication.DesktopAction:
                DoDesktopAction((RemoteDesktopAction)parameter[1], parameter, 2);
                break;

            case RemoteDesktopCommunication.ChangeDrawCursor:
                lock (_streamComponentsLock)
                {
                    if (parameter[1] == 1)
                    {
                        _drawCursor        = true;
                        _cursorStreamCodec = new CursorStreamCodec();
                    }
                    else
                    {
                        _cursorStreamCodec?.Dispose();
                        _drawCursor = false;
                    }
                }
                break;
            }
        }
Exemple #5
0
        private void button_Click(object sender, RoutedEventArgs e)
        {
            _dispatcherTimer = new DispatcherTimer {
                Interval = TimeSpan.FromSeconds(1)
            };
            _dispatcherTimer.Tick += DispatcherTimerOnTick;
            _dispatcherTimer.Start();

            new Thread(() =>
            {
                using (var streamCodec = new UnsafeStreamCodec(new JpgCompression(70),
                                                               UnsafeStreamCodecParameters.None))
                    using (var decoderCodec = new UnsafeStreamCodec(new JpgCompression(70),
                                                                    UnsafeStreamCodecParameters.None))
                        using (var cursorCodec = new CursorStreamCodec())
                            using (var decodeCursorCodec = new CursorStreamCodec())
                                using (var screenService = new FrontBufferService())
                                {
                                    streamCodec.ImageQuality = 70;
                                    screenService.Initialize(0);
                                    WriteableBitmap currentWriteableBitmap = null;

                                    while (!_isClosed)
                                    {
                                        var sw   = Stopwatch.StartNew();
                                        var data = screenService.CaptureScreen(streamCodec, cursorCodec, true);
                                        if (data == null)
                                        {
                                            continue;
                                        }
                                        //Debug.Print($"Screen captured ({sw.ElapsedMilliseconds})");

                                        unsafe
                                        {
                                            byte[] bytes;
                                            using (var ms = new MemoryStream())
                                            {
                                                data.WriteIntoStream(ms);
                                                bytes = ms.ToArray();
                                            }

                                            var cursorData = cursorCodec.CodeCursor();

                                            fixed(byte *bytePtr = bytes)
                                            {
                                                sw.Reset();
                                                //Debug.Print("Decode " + bytes.Length);
                                                var newBitmap =
                                                    decoderCodec.AppendModifier(decodeCursorCodec.CreateModifierTask(cursorData, 0,
                                                                                                                     cursorData.Length)).DecodeData(bytePtr, (uint)bytes.Length, Dispatcher);
                                                //Debug.Print($"Screen decoded ({sw.ElapsedMilliseconds})");
                                                if (newBitmap != currentWriteableBitmap)
                                                {
                                                    currentWriteableBitmap = newBitmap;
                                                    Dispatcher.Invoke(() => ImageAsd.Source = currentWriteableBitmap);
                                                }
                                                Interlocked.Increment(ref _currentFps);
                                            }
                                        }
                                    }
                                }
            }).Start();
        }