Exemple #1
0
        //FreeRDP - A Free Remote Desktop Protocol Client (https://github.com/FreeRDP/FreeRDP)
        //Usage: https://github.com/awakecoding/FreeRDP-Manuals/blob/master/User/FreeRDP-User-Manual.markdown
        public void StartProcess(
            int remoteSessionId,
            string serverAddress,
            string userDomain,
            string userName,
            string userPassword,
            string clientWidth,
            string clientHeight,
            bool debug)
        {
            try
            {
                // set the remote session id
                // the wcf service binding "wsDualHttpBinding" is "perSession" by default (maintain 1 service instance per client)
                // as there is 1 client per remote session, the remote session id is set for the current service instance
                _remoteSessionId = remoteSessionId;

                // as the rdp server uses the client numlock state, ensure it's off
                // server side, ensure that HKEY_USERS\.DEFAULT\Control Panel\Keyboard: InitialKeyboardIndicators is set to 0 (numlock off)
                SetNumLock(false);

                _process = new Process();

                if (Environment.UserInteractive)
                {
                    var pathParts = AppDomain.CurrentDomain.BaseDirectory.Split(new[] { @"\" }, StringSplitOptions.RemoveEmptyEntries);
                    _process.StartInfo.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\..\Myrtille.RDP", pathParts[pathParts.Length - 1], "wfreerdp.exe");
                }
                else
                {
                    _process.StartInfo.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wfreerdp.exe");
                }

                // ensure the FreeRDP executable does exists
                if (!File.Exists(_process.StartInfo.FileName))
                {
                    var msg = "The FreeRDP executable is missing. Please read documentation for steps to build it";
                    if (Environment.UserInteractive)
                    {
                        MessageBox.Show(msg);
                    }
                    Trace.TraceError(msg);
                    return;
                }

                _process.StartInfo.Arguments =
                    "/myrtille-sid:" + _remoteSessionId +                                                           // session id
                    (!Environment.UserInteractive ? string.Empty : " /myrtille-window") +                           // session window
                    (!debug ? string.Empty : " /myrtille-log") +                                                    // session log
                    " /v:" + (string.IsNullOrEmpty(serverAddress) ? "localhost" : serverAddress) +                  // server
                    (string.IsNullOrEmpty(userDomain) ? string.Empty : " /d:" + userDomain) +                       // domain
                    (string.IsNullOrEmpty(userName) ? string.Empty : " /u:" + userName) +                           // user
                    (string.IsNullOrEmpty(userPassword) ? string.Empty : " /p:" + userPassword) +                   // password
                    " /w:" + (string.IsNullOrEmpty(clientWidth) ? "1024" : clientWidth) +                           // display width
                    " /h:" + (string.IsNullOrEmpty(clientHeight) ? "768" : clientHeight) +                          // display height
                    " /bpp:16" +                                                                                    // color depth
                    //" /gdi:hw" +                                                                                  // gdi mode (sw: software, hw: hardware). auto-detected
                    " /network:modem" +                                                                             // network profile
                    " /compression" +                                                                               // bulk compression (level is autodetected from the rdp version)
                    " -sec-tls" +                                                                                   // tls encryption
                    " -mouse-motion" +                                                                              // mouse motion
                    " +bitmap-cache" +                                                                              // bitmap cache
                    " -offscreen-cache" +                                                                           // offscreen cache
                    " +glyph-cache" +                                                                               // glyph cache
                    " -async-input" +                                                                               // async input
                    " -async-update" +                                                                              // async update
                    " -async-channels" +                                                                            // async channels
                    " -async-transport" +                                                                           // async transport
                    " /clipboard" +                                                                                 // clipboard support
                    " /audio-mode:2";                                                                               // audio mode (not supported for now, 2: do not play)

                if (!Environment.UserInteractive)
                {
                    _process.StartInfo.UseShellExecute        = false;
                    _process.StartInfo.RedirectStandardError  = true;
                    _process.StartInfo.RedirectStandardInput  = true;
                    _process.StartInfo.RedirectStandardOutput = true;
                    _process.StartInfo.CreateNoWindow         = true;
                    _process.StartInfo.ErrorDialog            = false;
                    _process.StartInfo.WindowStyle            = ProcessWindowStyle.Hidden;
                }

                _process.EnableRaisingEvents = true;
                _process.Exited += ProcessExited;

                // set the callback instance
                // the wcf service binding "wsDualHttpBinding" allows for duplex communication
                _callback = OperationContext.Current.GetCallbackChannel <IRemoteSessionProcessCallback>();

                _process.Start();

                Trace.TraceInformation("Started rdp client process, remote session {0}", _remoteSessionId);
            }
            catch (Exception exc)
            {
                Trace.TraceError("Failed to start rdp client process, remote session {0} ({1})", _remoteSessionId, exc);
            }
        }
Exemple #2
0
        //FreeRDP - A Free Remote Desktop Protocol Client (https://github.com/FreeRDP/FreeRDP)
        //Usage: https://github.com/awakecoding/FreeRDP-Manuals/blob/master/User/FreeRDP-User-Manual.markdown
        public void StartProcess(
            int remoteSessionId,
            int clientWidth,
            int clientHeight)
        {
            try
            {
                // set the remote session id
                // the wcf service binding "wsDualHttpBinding" is "perSession" by default (maintain 1 service instance per client)
                // as there is 1 client per remote session, the remote session id is set for the current service instance
                _remoteSessionId = remoteSessionId;

                // as the rdp server uses the client numlock state, ensure it's off
                // server side, ensure that HKEY_USERS\.DEFAULT\Control Panel\Keyboard: InitialKeyboardIndicators is set to 0 (numlock off)
                SetNumLock(false);

                _process = new Process();

                // see https://github.com/cedrozor/myrtille/blob/master/DOCUMENTATION.md#build for information and steps to build FreeRDP along with myrtille

                if (Environment.UserInteractive)
                {
                    var pathParts = AppDomain.CurrentDomain.BaseDirectory.Split(new[] { @"\" }, StringSplitOptions.RemoveEmptyEntries);
                    _process.StartInfo.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\..\Myrtille.RDP\FreeRDP", pathParts[pathParts.Length - 1], "wfreerdp.exe");
                }
                else
                {
                    _process.StartInfo.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wfreerdp.exe");
                }

                // ensure the FreeRDP executable does exists
                if (!File.Exists(_process.StartInfo.FileName))
                {
                    var msg = "The FreeRDP executable is missing. Please read documentation for steps to build it";
                    if (Environment.UserInteractive)
                    {
                        MessageBox.Show(msg);
                    }
                    Trace.TraceError(msg);
                    return;
                }

                // log remote session events into a file (located into <Myrtille folder>\log)
                var remoteSessionLog = false;
                if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["RemoteSessionLog"]))
                {
                    remoteSessionLog = bool.Parse(ConfigurationManager.AppSettings["RemoteSessionLog"]);
                }

                // https://github.com/FreeRDP/FreeRDP/wiki/CommandLineInterface
                // Syntax: /flag enables flag, +toggle or -toggle enables or disables toggle. /toggle and +toggle are the same. Options with values work like this: /option:<value>
                // as the process command line can be displayed into the task manager / process explorer, the connection settings (including user credentials) are now passed to the rdp client through the inputs pipe
                _process.StartInfo.Arguments =
                    "/myrtille-sid:" + _remoteSessionId +                                                           // session id
                    (!Environment.UserInteractive ? string.Empty : " /myrtille-window") +                           // session window
                    (!remoteSessionLog ? string.Empty : " /myrtille-log") +                                         // session log
                    " /w:" + clientWidth +                                                                          // display width
                    " /h:" + clientHeight +                                                                         // display height
                    " /bpp:16" +                                                                                    // color depth
                    " /gdi:sw" +                                                                                    // gdi mode (sw: software, hw: hardware). forced software because there is a palette issue with windows server 2008; also, the performance gain is small and even null on most virtual machines, when hardware isn't available
                    " -wallpaper" +                                                                                 // wallpaper
                    " -aero" +                                                                                      // desktop composition
                    " -window-drag" +                                                                               // window drag
                    " -menu-anims" +                                                                                // menu animations
                    " -themes" +                                                                                    // themes
                    " +fonts" +                                                                                     // smooth fonts (requires ClearType enabled on the remote server)
                    " +compression" +                                                                               // bulk compression (level is autodetected from the rdp version)
                    " /cert-ignore" +                                                                               // ignore certificate warning (when using NLA); may happen, for example, with a self-signed certificate (not trusted) or if the server joined a domain after the certificate was issued (name mismatch). more details here: http://www.vkernel.ro/blog/configuring-certificates-in-2012r2-remote-desktop-services-rds
                    " -mouse-motion" +                                                                              // mouse motion
                    " +bitmap-cache" +                                                                              // bitmap cache
                    " -offscreen-cache" +                                                                           // offscreen cache
                    " +glyph-cache" +                                                                               // glyph cache
                    " -async-input" +                                                                               // async input
                    " -async-update" +                                                                              // async update
                    " -async-channels" +                                                                            // async channels
                    " -async-transport" +                                                                           // async transport
                    " +clipboard" +                                                                                 // clipboard support
                    " /audio-mode:2";                                                                               // audio mode (not supported for now, 2: do not play)

                if (!Environment.UserInteractive)
                {
                    _process.StartInfo.UseShellExecute        = false;
                    _process.StartInfo.RedirectStandardError  = true;
                    _process.StartInfo.RedirectStandardInput  = true;
                    _process.StartInfo.RedirectStandardOutput = true;
                    _process.StartInfo.CreateNoWindow         = true;
                    _process.StartInfo.ErrorDialog            = false;
                    _process.StartInfo.WindowStyle            = ProcessWindowStyle.Hidden;
                }

                _process.EnableRaisingEvents = true;
                _process.Exited += ProcessExited;

                // set the callback instance
                // the wcf service binding "wsDualHttpBinding" allows for duplex communication
                _callback = OperationContext.Current.GetCallbackChannel <IRemoteSessionProcessCallback>();

                _process.Start();

                Trace.TraceInformation("Started remote session {0}", _remoteSessionId);
            }
            catch (Exception exc)
            {
                Trace.TraceError("Failed to start rdp client process, remote session {0} ({1})", _remoteSessionId, exc);
            }
        }
Exemple #3
0
        public void StartProcess(
            int remoteSessionId,
            HostTypeEnum hostType,
            SecurityProtocolEnum securityProtocol,
            string serverAddress,
            string userDomain,
            string userName,
            string startProgram,
            int clientWidth,
            int clientHeight,
            bool allowRemoteClipboard,
            bool allowPrintDownload)
        {
            Trace.TraceInformation("Connecting remote session {0}, type {1}, security {2}, server {3}, domain {4}, user {5}, program {6}",
                                   remoteSessionId,
                                   hostType,
                                   hostType == HostTypeEnum.RDP ? securityProtocol.ToString().ToUpper() : "N/A",
                                   serverAddress,
                                   hostType == HostTypeEnum.RDP ? (string.IsNullOrEmpty(userDomain) ? "(none)" : userDomain) : "N/A",
                                   userName,
                                   hostType == HostTypeEnum.RDP ? (string.IsNullOrEmpty(startProgram) ? "(none)" : startProgram) : "N/A");

            try
            {
                // set the remote session id
                // the wcf service binding "wsDualHttpBinding" is "perSession" by default (maintain 1 service instance per client)
                // as there is 1 client per remote session, the remote session id is set for the current service instance
                _remoteSessionId = remoteSessionId;

                _process = new Process();

                // select the host client executable based on the host type
                var clientFilePath = string.Empty;
                var clientFileName = string.Empty;
                switch (hostType)
                {
                // see https://github.com/cedrozor/myrtille/blob/master/DOCUMENTATION.md#build for information and steps to build FreeRDP along with myrtille
                case HostTypeEnum.RDP:
                    clientFilePath = @"Myrtille.RDP\FreeRDP";
                    clientFileName = "wfreerdp.exe";
                    break;

                case HostTypeEnum.SSH:
                    clientFilePath = @"Myrtille.SSH\bin";
                    clientFileName = "Myrtille.SSH.exe";
                    break;
                }

                if (Environment.UserInteractive)
                {
                    _process.StartInfo.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory.Replace(@"Myrtille.Services\bin", clientFilePath), clientFileName);
                }
                else
                {
                    _process.StartInfo.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, clientFileName);
                }

                // ensure the host client executable does exists
                if (!File.Exists(_process.StartInfo.FileName))
                {
                    var msg = string.Format("The host client executable ({0}) is missing. Please read documentation for steps to build it", _process.StartInfo.FileName);
                    if (Environment.UserInteractive)
                    {
                        MessageBox.Show(msg);
                    }
                    Trace.TraceError(msg);
                    return;
                }

                // log remote session events into a file (located into <Myrtille folder>\log)
                bool remoteSessionLog;
                if (!bool.TryParse(ConfigurationManager.AppSettings["RemoteSessionLog"], out remoteSessionLog))
                {
                    remoteSessionLog = false;
                }

                #region RDP

                if (hostType == HostTypeEnum.RDP)
                {
                    // color depth
                    int bpp;
                    if (!int.TryParse(ConfigurationManager.AppSettings["FreeRDPBpp"], out bpp))
                    {
                        bpp = 16;
                    }

                    // gdi mode (sw: software, hw: hardware). default software because there is a palette issue with windows server 2008; also, the performance gain is small and even null on most virtual machines, when hardware isn't available
                    var gdi = "sw";
                    if (ConfigurationManager.AppSettings["FreeRDPGdi"] != null)
                    {
                        gdi = ConfigurationManager.AppSettings["FreeRDPGdi"];
                    }

                    // wallpaper
                    bool wallpaper;
                    if (!bool.TryParse(ConfigurationManager.AppSettings["FreeRDPWallpaper"], out wallpaper))
                    {
                        wallpaper = false;
                    }

                    // desktop composition
                    bool aero;
                    if (!bool.TryParse(ConfigurationManager.AppSettings["FreeRDPAero"], out aero))
                    {
                        aero = false;
                    }

                    // window drag
                    bool windowDrag;
                    if (!bool.TryParse(ConfigurationManager.AppSettings["FreeRDPWindowDrag"], out windowDrag))
                    {
                        windowDrag = false;
                    }

                    // menu animations
                    bool menuAnims;
                    if (!bool.TryParse(ConfigurationManager.AppSettings["FreeRDPMenuAnims"], out menuAnims))
                    {
                        menuAnims = false;
                    }

                    // themes
                    bool themes;
                    if (!bool.TryParse(ConfigurationManager.AppSettings["FreeRDPThemes"], out themes))
                    {
                        themes = false;
                    }

                    // smooth fonts (requires ClearType enabled on the remote server)
                    bool smoothFonts;
                    if (!bool.TryParse(ConfigurationManager.AppSettings["FreeRDPSmoothFonts"], out smoothFonts))
                    {
                        smoothFonts = true;
                    }

                    // ignore certificate warning (when using NLA); may happen, for example, with a self-signed certificate (not trusted) or if the server joined a domain after the certificate was issued (name mismatch). more details here: http://www.vkernel.ro/blog/configuring-certificates-in-2012r2-remote-desktop-services-rds
                    bool certIgnore;
                    if (!bool.TryParse(ConfigurationManager.AppSettings["FreeRDPCertIgnore"], out certIgnore))
                    {
                        certIgnore = true;
                    }

                    // pdf virtual printer redirection

                    // TOCHECK: for some reason, using the exact pdf virtual printer driver name ("PDF Scribe Virtual Printer") doesn't work (the printer doesn't show into the remote session) with wfreerdp, while it works with mstsc (!)
                    // it may have something to do with the driver not being installed on the remote server, but as the underlying driver is the standard "Microsoft Postscript Printer Driver (v3)" (pscript5.dll), it should have worked...
                    // as a workaround for now, the same way freerdp does in CUPS mode (printer redirection under Linux), it's possible to use the "MS Publisher Imagesetter" driver; it's also based on pscript5.dll and support basic print features (portrait/landscape orientation, custom fonts, color mode, etc.)

                    // as the rdp server uses the client numlock state, ensure it's off
                    // server side, ensure that HKEY_USERS\.DEFAULT\Control Panel\Keyboard: InitialKeyboardIndicators is set to 0 (numlock off)
                    SetNumLock(false);

                    // https://github.com/FreeRDP/FreeRDP/wiki/CommandLineInterface
                    // Syntax: /flag enables flag, +toggle or -toggle enables or disables toggle. /toggle and +toggle are the same. Options with values work like this: /option:<value>
                    // as the process command line can be displayed into the task manager / process explorer, the connection settings (including user credentials) are now passed to the rdp client through the inputs pipe
                    _process.StartInfo.Arguments =
                        "/myrtille-sid:" + _remoteSessionId +                                                                       // session id
                        (!Environment.UserInteractive ? string.Empty : " /myrtille-window") +                                       // session window
                        (!remoteSessionLog ? string.Empty : " /myrtille-log") +                                                     // session log
                        " /w:" + clientWidth +                                                                                      // display width
                        " /h:" + clientHeight +                                                                                     // display height
                        " /bpp:" + bpp +                                                                                            // color depth
                        " /gdi:" + gdi +                                                                                            // gdi mode (sw: software, hw: hardware)
                        (wallpaper ? " +" : " -") + "wallpaper" +                                                                   // wallpaper
                        (aero ? " +" : " -") + "aero" +                                                                             // desktop composition
                        (windowDrag ? " +" : " -") + "window-drag" +                                                                // window drag
                        (menuAnims ? " +" : " -") + "menu-anims" +                                                                  // menu animations
                        (themes ? " +" : " -") + "themes" +                                                                         // themes
                        (smoothFonts ? " +" : " -") + "fonts" +                                                                     // smooth fonts (requires ClearType enabled on the remote server)
                        " +compression" +                                                                                           // bulk compression (level is autodetected from the rdp version)
                        (certIgnore ? " /cert-ignore" : string.Empty) +                                                             // ignore certificate warning (when using NLA)
                        (allowPrintDownload ? " /printer:\"Myrtille PDF\",\"MS Publisher Imagesetter\"" : string.Empty) +           // pdf virtual printer
                        " -mouse-motion" +                                                                                          // mouse motion
                        " +bitmap-cache" +                                                                                          // bitmap cache
                        " -offscreen-cache" +                                                                                       // offscreen cache
                        " +glyph-cache" +                                                                                           // glyph cache
                        " -async-input" +                                                                                           // async input
                        " -async-update" +                                                                                          // async update
                        " -async-channels" +                                                                                        // async channels
                        " -async-transport" +                                                                                       // async transport
                        (allowRemoteClipboard ? " +" : " -") + "clipboard" +                                                        // clipboard support
                        (securityProtocol != SecurityProtocolEnum.auto ? " /sec:" + securityProtocol.ToString() : string.Empty) +   // security protocol
                        " /audio-mode:2";                                                                                           // audio mode (not supported for now, 2: do not play)
                }

                #endregion

                #region SSH

                else
                {
                    _process.StartInfo.Arguments =
                        "/myrtille-sid:" + _remoteSessionId +                                                                       // session id
                        (!Environment.UserInteractive ? string.Empty : " /myrtille-window") +                                       // session window
                        (!remoteSessionLog ? string.Empty : " /myrtille-log") +                                                     // session log
                        " /w:" + clientWidth +                                                                                      // display width
                        " /h:" + clientHeight;                                                                                      // display height
                }

                #endregion

                if (!Environment.UserInteractive)
                {
                    _process.StartInfo.UseShellExecute        = false;
                    _process.StartInfo.RedirectStandardError  = true;
                    _process.StartInfo.RedirectStandardInput  = true;
                    _process.StartInfo.RedirectStandardOutput = true;
                    _process.StartInfo.CreateNoWindow         = true;
                    _process.StartInfo.ErrorDialog            = false;
                    _process.StartInfo.WindowStyle            = ProcessWindowStyle.Hidden;
                }

                _process.EnableRaisingEvents = true;
                _process.Exited += ProcessExited;

                // set the callback instance
                // the wcf service binding "wsDualHttpBinding" allows for duplex communication
                _callback = OperationContext.Current.GetCallbackChannel <IRemoteSessionProcessCallback>();

                _process.Start();
            }
            catch (Exception exc)
            {
                Trace.TraceError("Failed to start the host client process, remote session {0} ({1})", _remoteSessionId, exc);
            }
        }
        //FreeRDP - A Free Remote Desktop Protocol Client (https://github.com/FreeRDP/FreeRDP)
        //Usage: https://github.com/awakecoding/FreeRDP-Manuals/blob/master/User/FreeRDP-User-Manual.markdown
        public void StartProcess(
            int remoteSessionId,
            string serverAddress,
            string userDomain,
            string userName,
            string userPassword,
            int clientWidth,
            int clientHeight,
            string program)
        {
            try
            {
                // set the remote session id
                // the wcf service binding "wsDualHttpBinding" is "perSession" by default (maintain 1 service instance per client)
                // as there is 1 client per remote session, the remote session id is set for the current service instance
                _remoteSessionId = remoteSessionId;

                // as the rdp server uses the client numlock state, ensure it's off
                // server side, ensure that HKEY_USERS\.DEFAULT\Control Panel\Keyboard: InitialKeyboardIndicators is set to 0 (numlock off)
                SetNumLock(false);

                _process = new Process();

                // see https://github.com/cedrozor/myrtille/blob/master/DOCUMENTATION.md#build for information and steps to build FreeRDP along with myrtille

                if (Environment.UserInteractive)
                {
                    var pathParts = AppDomain.CurrentDomain.BaseDirectory.Split(new[] { @"\" }, StringSplitOptions.RemoveEmptyEntries);
                    _process.StartInfo.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\..\..\Myrtille.RDP\FreeRDP", pathParts[pathParts.Length - 1], "wfreerdp.exe");
                }
                else
                {
                    _process.StartInfo.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wfreerdp.exe");
                }

                // ensure the FreeRDP executable does exists
                if (!File.Exists(_process.StartInfo.FileName))
                {
                    var msg = "The FreeRDP executable is missing. Please read documentation for steps to build it";
                    if (Environment.UserInteractive)
                    {
                        MessageBox.Show(msg);
                    }
                    Trace.TraceError(msg);
                    return;
                }

                // log remote session events into a file (located into <Myrtille folder>\log)
                var remoteSessionLog = false;
                if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["RemoteSessionLog"]))
                {
                    remoteSessionLog = bool.Parse(ConfigurationManager.AppSettings["RemoteSessionLog"]);
                }

                // https://github.com/FreeRDP/FreeRDP/wiki/CommandLineInterface
                // Syntax: /flag enables flag, +toggle or -toggle enables or disables toggle. /toggle and +toggle are the same. Options with values work like this: /option:<value>
                _process.StartInfo.Arguments =
                    "/myrtille-sid:" + _remoteSessionId +                                                           // session id
                    (!Environment.UserInteractive ? string.Empty : " /myrtille-window") +                           // session window
                    (!remoteSessionLog ? string.Empty : " /myrtille-log") +                                         // session log
                    " /v:" + (string.IsNullOrEmpty(serverAddress) ? "localhost" : serverAddress) +                  // server
                    (string.IsNullOrEmpty(userDomain) ? string.Empty : " /d:" + userDomain) +                       // domain
                    (string.IsNullOrEmpty(userName) ? string.Empty : " /u:" + userName) +                           // user
                    (string.IsNullOrEmpty(userPassword) ? string.Empty : " /p:" + userPassword) +                   // password
                    " /w:" + clientWidth +                                                                          // display width
                    " /h:" + clientHeight +                                                                         // display height
                    " /bpp:16" +                                                                                    // color depth
                    " /gdi:sw" +                                                                                    // gdi mode (sw: software, hw: hardware). forced software because there is a palette issue with windows server 2008; also, the performance gain is small and even null on most virtual machines, when hardware isn't available
                    " /network:modem" +                                                                             // network profile
                    " +compression" +                                                                               // bulk compression (level is autodetected from the rdp version)
                    " -sec-tls" +                                                                                   // tls encryption
                    " -mouse-motion" +                                                                              // mouse motion
                    " +bitmap-cache" +                                                                              // bitmap cache
                    " -offscreen-cache" +                                                                           // offscreen cache
                    " +glyph-cache" +                                                                               // glyph cache
                    " -async-input" +                                                                               // async input
                    " -async-update" +                                                                              // async update
                    " -async-channels" +                                                                            // async channels
                    " -async-transport" +                                                                           // async transport
                    " +clipboard" +                                                                                 // clipboard support
                    " /audio-mode:2" +                                                                              // audio mode (not supported for now, 2: do not play)
                    (string.IsNullOrEmpty(program) ? string.Empty : " /shell:\"" + program + "\"");                 // program to run

                if (!Environment.UserInteractive)
                {
                    _process.StartInfo.UseShellExecute        = false;
                    _process.StartInfo.RedirectStandardError  = true;
                    _process.StartInfo.RedirectStandardInput  = true;
                    _process.StartInfo.RedirectStandardOutput = true;
                    _process.StartInfo.CreateNoWindow         = true;
                    _process.StartInfo.ErrorDialog            = false;
                    _process.StartInfo.WindowStyle            = ProcessWindowStyle.Hidden;
                }

                _process.EnableRaisingEvents = true;
                _process.Exited += ProcessExited;

                // set the callback instance
                // the wcf service binding "wsDualHttpBinding" allows for duplex communication
                _callback = OperationContext.Current.GetCallbackChannel <IRemoteSessionProcessCallback>();

                _process.Start();

                Trace.TraceInformation("Started remote session {0}", _remoteSessionId);
            }
            catch (Exception exc)
            {
                Trace.TraceError("Failed to start rdp client process, remote session {0} ({1})", _remoteSessionId, exc);
            }
        }
        //FreeRDP - A Free Remote Desktop Protocol Client (https://github.com/FreeRDP/FreeRDP)
        //Usage: https://github.com/awakecoding/FreeRDP-Manuals/blob/master/User/FreeRDP-User-Manual.markdown
        public void StartProcess(
            int remoteSessionId,
            string serverAddress,
            string userDomain,
            string userName,
            string startProgram,
            int clientWidth,
            int clientHeight,
            bool allowRemoteClipboard,
            SecurityProtocolEnum securityProtocol)
        {
            Trace.TraceInformation("Connecting remote session {0}, server {1}, domain {2}, user {3}, program {4}", remoteSessionId, serverAddress, string.IsNullOrEmpty(userDomain) ? "(none)" : userDomain, userName, string.IsNullOrEmpty(startProgram) ? "(none)" : startProgram);

            try
            {
                // set the remote session id
                // the wcf service binding "wsDualHttpBinding" is "perSession" by default (maintain 1 service instance per client)
                // as there is 1 client per remote session, the remote session id is set for the current service instance
                _remoteSessionId = remoteSessionId;

                // as the rdp server uses the client numlock state, ensure it's off
                // server side, ensure that HKEY_USERS\.DEFAULT\Control Panel\Keyboard: InitialKeyboardIndicators is set to 0 (numlock off)
                SetNumLock(false);

                _process = new Process();

                // see https://github.com/cedrozor/myrtille/blob/master/DOCUMENTATION.md#build for information and steps to build FreeRDP along with myrtille

                if (Environment.UserInteractive)
                {
                    _process.StartInfo.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory.Replace(@"Myrtille.Services\bin", @"Myrtille.RDP\FreeRDP"), "wfreerdp.exe");
                }
                else
                {
                    _process.StartInfo.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wfreerdp.exe");
                }

                // ensure the FreeRDP executable does exists
                if (!File.Exists(_process.StartInfo.FileName))
                {
                    var msg = "The FreeRDP executable is missing. Please read documentation for steps to build it";
                    if (Environment.UserInteractive)
                    {
                        MessageBox.Show(msg);
                    }
                    Trace.TraceError(msg);
                    return;
                }

                // log remote session events into a file (located into <Myrtille folder>\log)
                var  remoteSessionLog = false;
                bool bResult          = false;
                if (bool.TryParse(ConfigurationManager.AppSettings["RemoteSessionLog"], out bResult))
                {
                    remoteSessionLog = bResult;
                }

                #region FreeRDP params

                // color depth
                var bpp     = 16;
                int iResult = 16;
                if (int.TryParse(ConfigurationManager.AppSettings["FreeRDPBpp"], out iResult))
                {
                    bpp = iResult;
                }

                // gdi mode (sw: software, hw: hardware). default software because there is a palette issue with windows server 2008; also, the performance gain is small and even null on most virtual machines, when hardware isn't available
                var gdi = "sw";
                if (ConfigurationManager.AppSettings["FreeRDPGdi"] != null)
                {
                    gdi = ConfigurationManager.AppSettings["FreeRDPGdi"];
                }

                // wallpaper
                var wallpaper = false;
                if (bool.TryParse(ConfigurationManager.AppSettings["FreeRDPWallpaper"], out bResult))
                {
                    wallpaper = bResult;
                }


                // desktop composition
                var aero = false;
                if (bool.TryParse(ConfigurationManager.AppSettings["FreeRDPAero"], out bResult))
                {
                    aero = bResult;
                }

                // window drag
                var windowDrag = false;
                if (bool.TryParse(ConfigurationManager.AppSettings["FreeRDPWindowDrag"], out bResult))
                {
                    windowDrag = bResult;
                }

                // menu animations
                var menuAnims = false;
                if (bool.TryParse(ConfigurationManager.AppSettings["FreeRDPMenuAnims"], out bResult))
                {
                    menuAnims = bResult;
                }

                // themes
                var themes = false;
                if (bool.TryParse(ConfigurationManager.AppSettings["FreeRDPThemes"], out bResult))
                {
                    themes = bResult;
                }

                // smooth fonts (requires ClearType enabled on the remote server)
                var smoothFonts = true;
                if (bool.TryParse(ConfigurationManager.AppSettings["FreeRDPSmoothFonts"], out bResult))
                {
                    smoothFonts = bResult;
                }

                // ignore certificate warning (when using NLA); may happen, for example, with a self-signed certificate (not trusted) or if the server joined a domain after the certificate was issued (name mismatch). more details here: http://www.vkernel.ro/blog/configuring-certificates-in-2012r2-remote-desktop-services-rds
                var certIgnore = true;
                if (bool.TryParse(ConfigurationManager.AppSettings["FreeRDPCertIgnore"], out bResult))
                {
                    certIgnore = bResult;
                }

                #endregion

                // https://github.com/FreeRDP/FreeRDP/wiki/CommandLineInterface
                // Syntax: /flag enables flag, +toggle or -toggle enables or disables toggle. /toggle and +toggle are the same. Options with values work like this: /option:<value>
                // as the process command line can be displayed into the task manager / process explorer, the connection settings (including user credentials) are now passed to the rdp client through the inputs pipe
                _process.StartInfo.Arguments =
                    "/myrtille-sid:" + _remoteSessionId +                                                           // session id
                    (!Environment.UserInteractive ? string.Empty : " /myrtille-window") +                           // session window
                    (!remoteSessionLog ? string.Empty : " /myrtille-log") +                                         // session log
                    " /w:" + clientWidth +                                                                          // display width
                    " /h:" + clientHeight +                                                                         // display height
                    " /bpp:" + bpp +                                                                                // color depth
                    " /gdi:" + gdi +                                                                                // gdi mode (sw: software, hw: hardware)
                    (wallpaper ? " +" : " -") + "wallpaper" +                                                       // wallpaper
                    (aero ? " +" : " -") + "aero" +                                                                 // desktop composition
                    (windowDrag ? " +" : " -") + "window-drag" +                                                    // window drag
                    (menuAnims ? " +" : " -") + "menu-anims" +                                                      // menu animations
                    (themes ? " +" : " -") + "themes" +                                                             // themes
                    (smoothFonts ? " +" : " -") + "fonts" +                                                         // smooth fonts (requires ClearType enabled on the remote server)
                    " +compression" +                                                                               // bulk compression (level is autodetected from the rdp version)
                    (certIgnore ? " /cert-ignore" : "") +                                                           // ignore certificate warning (when using NLA)
                    " -mouse-motion" +                                                                              // mouse motion
                    " +bitmap-cache" +                                                                              // bitmap cache
                    " -offscreen-cache" +                                                                           // offscreen cache
                    " +glyph-cache" +                                                                               // glyph cache
                    " -async-input" +                                                                               // async input
                    " -async-update" +                                                                              // async update
                    " -async-channels" +                                                                            // async channels
                    " -async-transport" +                                                                           // async transport
                    (allowRemoteClipboard ? " +" : " -") + "clipboard" +                                            // clipboard support
                    (securityProtocol != SecurityProtocolEnum.auto ? " /sec:" + securityProtocol.ToString() : "") + // security protocol
                    " /audio-mode:2";                                                                               // audio mode (not supported for now, 2: do not play)

                if (!Environment.UserInteractive)
                {
                    _process.StartInfo.UseShellExecute        = false;
                    _process.StartInfo.RedirectStandardError  = true;
                    _process.StartInfo.RedirectStandardInput  = true;
                    _process.StartInfo.RedirectStandardOutput = true;
                    _process.StartInfo.CreateNoWindow         = true;
                    _process.StartInfo.ErrorDialog            = false;
                    _process.StartInfo.WindowStyle            = ProcessWindowStyle.Hidden;
                }

                _process.EnableRaisingEvents = true;
                _process.Exited += ProcessExited;

                // set the callback instance
                // the wcf service binding "wsDualHttpBinding" allows for duplex communication
                _callback = OperationContext.Current.GetCallbackChannel <IRemoteSessionProcessCallback>();

                _process.Start();
            }
            catch (Exception exc)
            {
                Trace.TraceError("Failed to start rdp client process, remote session {0} ({1})", _remoteSessionId, exc);
            }
        }
Exemple #6
0
        //FreeRDP - A Free Remote Desktop Protocol Client
        //See http://freerdp.sourceforge.net for more information
        //Usage: xfreerdp [options] server:port
        //-a: color depth (8, 15, 16, 24 or 32)
        //-u: username
        //-p: password
        //-d: domain
        //-s: shell
        //-c: directory
        //-g: geometry, using format WxH or X%, default is 800x600
        //-t: alternative port number, default is 3389
        //-n: hostname
        //-o: console audio
        //-0: console session
        //-f: fullscreen mode
        //-z: enable bulk compression
        //-x: performance flags (m, b or l for modem, broadband or lan)
        //-i: remote session id
        //--no-rdp: disable Standard RDP encryption
        //--no-tls: disable TLS encryption
        //--no-nla: disable network level authentication
        //--sec: force protocol security (rdp, tls or nla)
        //--no-osb: disable off screen bitmaps, default on
        //--no-window: don't open a standard window for user interaction (freerdp runs as process only); also enforces no console window
        //--no-console: don't open a console window for debug output
        //--debug-log: write debug output to freerdp.log
        //--debug-log-process: write debug output to FreeRDP.wfreerdp.log; locate it into the parent "log" folder (among others myrtille logs) and stamp it with the FreeRDP.wfreerdp.exe process id
        //--version: Print out the version and exit
        //-h: show this help
        public void StartProcess(
            int remoteSessionId,
            string serverAddress,
            string userDomain,
            string userName,
            string userPassword,
            string clientWidth,
            string clientHeight,
            bool debug)
        {
            try
            {
                // set the remote session id
                // the wcf service binding "wsDualHttpBinding" is "perSession" by default (maintain 1 service instance per client)
                // as there is 1 client per remote session, the remote session id is set for the current service instance
                _remoteSessionId = remoteSessionId;

                // as the rdp server uses the client numlock state, ensure it's off
                // server side, ensure that HKEY_USERS\.DEFAULT\Control Panel\Keyboard: InitialKeyboardIndicators is set to 0 (numlock off)
                SetNumLock(false);

                _process = new Process();

                _process.StartInfo.FileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "FreeRDP.wfreerdp.exe");

                // ensure the FreeRDP executable does exists
                if (!File.Exists(_process.StartInfo.FileName))
                {
                    var msg = "The FreeRDP executable is missing. Please build the Myrtille.RDP/FreeRDP.wfreerdp project in order to generate it.";
                    if (Environment.UserInteractive)
                    {
                        MessageBox.Show(msg);
                    }
                    Trace.TraceError(msg);
                    return;
                }

                _process.StartInfo.Arguments =
                    "-i " + _remoteSessionId +
                    " -z" +
                    " -x m" +
                    " -g " + (string.IsNullOrEmpty(clientWidth) ? "1024" : clientWidth) + "x" + (string.IsNullOrEmpty(clientHeight) ? "768" : clientHeight) +
                    " -a 16" +
                    (string.IsNullOrEmpty(userDomain) ? string.Empty : " -d " + userDomain) +
                    (string.IsNullOrEmpty(userName) ? string.Empty : " -u " + userName) +
                    (string.IsNullOrEmpty(userPassword) ? string.Empty : " -p " + userPassword) +
                    (string.IsNullOrEmpty(serverAddress) ? " localhost" : " " + serverAddress) +
                    " --no-tls --no-nla --sec-rdp --no-osb" +
                    (!debug ? " --no-window --no-console" : (!Environment.UserInteractive ? " --no-window --no-console --debug-log-process" : string.Empty));

                if (!debug || !Environment.UserInteractive)
                {
                    _process.StartInfo.UseShellExecute        = false;
                    _process.StartInfo.RedirectStandardError  = true;
                    _process.StartInfo.RedirectStandardInput  = true;
                    _process.StartInfo.RedirectStandardOutput = true;
                    _process.StartInfo.CreateNoWindow         = true;
                    _process.StartInfo.ErrorDialog            = false;
                    _process.StartInfo.WindowStyle            = ProcessWindowStyle.Hidden;
                }

                _process.EnableRaisingEvents = true;
                _process.Exited += ProcessExited;

                // set the callback instance
                // the wcf service binding "wsDualHttpBinding" allows for duplex communication
                _callback = OperationContext.Current.GetCallbackChannel <IRemoteSessionProcessCallback>();

                _process.Start();

                Trace.TraceInformation("Started rdp client process, remote session {0}", _remoteSessionId);
            }
            catch (Exception exc)
            {
                Trace.TraceError("Failed to start rdp client process, remote session {0} ({1})", _remoteSessionId, exc);
            }
        }