예제 #1
0
        public void Start(CreateTerminalRequest request, TerminalsManager terminalsManager)
        {
            _enableBuffer = request.Profile.UseBuffer;

            _reader?.Dispose();
            _reader = null;

            Id = request.Id;
            _terminalsManager = terminalsManager;

            ShellExecutableName = Path.GetFileNameWithoutExtension(request.Profile.Location);
            var cwd = GetWorkingDirectory(request.Profile);

            var args = !string.IsNullOrWhiteSpace(request.Profile.Location)
                ? $"\"{request.Profile.Location}\" {request.Profile.Arguments}"
                : request.Profile.Arguments;

            _terminal              = new Terminal();
            _terminal.OutputReady += _terminal_OutputReady;
            _terminal.Exited      += _terminal_Exited;

            Task.Factory.StartNew(() => _terminal.Start(args, cwd,
                                                        terminalsManager.GetDefaultEnvironmentVariableString(request.Profile.EnvironmentVariables),
                                                        request.Size.Columns, request.Size.Rows));
        }
예제 #2
0
        public void Start(CreateTerminalRequest request, TerminalsManager terminalsManager)
        {
            Id = request.Id;
            _terminalsManager = terminalsManager;
            _terminalSize     = request.Size;

            ShellExecutableName = Path.GetFileNameWithoutExtension(request.Profile.Location);
            var cwd = GetWorkingDirectory(request.Profile);

            var args = string.Empty;

            if (!string.IsNullOrWhiteSpace(request.Profile.Location))
            {
                args = $"\"{request.Profile.Location}\" {request.Profile.Arguments}";
            }
            else
            {
                args = request.Profile.Arguments;
            }

            _terminal              = new Terminal();
            _terminal.OutputReady += _terminal_OutputReady;
            _terminal.Exited      += _terminal_Exited;
            Task.Run(() => _terminal.Start(args, cwd, terminalsManager.GetDefaultEnvironmentVariableString(request.Profile.EnvironmentVariables), request.Size.Columns, request.Size.Rows));
        }
        public CreateTerminalResponse CreateTerminal(CreateTerminalRequest request)
        {
            TerminalSession terminal;

            try
            {
                terminal = new TerminalSession(request);
            }
            catch (Exception e)
            {
                return(new CreateTerminalResponse {
                    Error = e.Message
                });
            }

            terminal.ConnectionClosed += OnTerminalConnectionClosed;
            _terminals.Add(terminal.Id, terminal);

            return(new CreateTerminalResponse
            {
                Success = true,
                Id = terminal.Id,
                WebSocketUrl = terminal.WebSocketUrl,
                ShellExecutableName = terminal.ShellExecutableName
            });
        }
예제 #4
0
        public CreateTerminalResponse CreateTerminal(CreateTerminalRequest request)
        {
            ITerminalSession terminal = null;

            try
            {
                if (request.SessionType == SessionType.WinPty)
                {
                    terminal = new WinPtySession();
                }
                else if (request.SessionType == SessionType.ConPty)
                {
                    terminal = new ConPtySession();
                }
                terminal.Start(request, this);
            }
            catch (Exception e)
            {
                return(new CreateTerminalResponse {
                    Error = e.ToString()
                });
            }

            terminal.ConnectionClosed += OnTerminalConnectionClosed;
            _terminals.Add(terminal.Id, terminal);
            return(new CreateTerminalResponse
            {
                Success = true,
                Id = terminal.Id,
                ShellExecutableName = terminal.ShellExecutableName
            });
        }
예제 #5
0
        public TerminalSession(CreateTerminalRequest request, TerminalsManager terminalsManager)
        {
            _terminalsManager = terminalsManager;

            var configHandle      = IntPtr.Zero;
            var spawnConfigHandle = IntPtr.Zero;
            var errorHandle       = IntPtr.Zero;

            try
            {
                configHandle = winpty_config_new(WINPTY_FLAG_COLOR_ESCAPES, out errorHandle);
                winpty_config_set_initial_size(configHandle, request.Size.Columns, request.Size.Rows);

                _handle = winpty_open(configHandle, out errorHandle);
                if (errorHandle != IntPtr.Zero)
                {
                    throw new Exception(winpty_error_msg(errorHandle));
                }

                string exe  = request.Profile.Location;
                string args = $"\"{exe}\" {request.Profile.Arguments}";
                string cwd  = GetWorkingDirectory(request.Profile);
                spawnConfigHandle = winpty_spawn_config_new(WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN, exe, args, cwd, null, out errorHandle);
                if (errorHandle != IntPtr.Zero)
                {
                    throw new Exception(winpty_error_msg(errorHandle).ToString());
                }

                _stdin  = CreatePipe(winpty_conin_name(_handle), PipeDirection.Out);
                _stdout = CreatePipe(winpty_conout_name(_handle), PipeDirection.In);

                if (!winpty_spawn(_handle, spawnConfigHandle, out IntPtr process, out IntPtr thread, out int procError, out errorHandle))
                {
                    throw new Exception($"Failed to start the shell process. Please check your shell settings.\nTried to start: {args}");
                }

                ShellExecutableName = Path.GetFileNameWithoutExtension(exe);
            }
            finally
            {
                winpty_config_free(configHandle);
                winpty_spawn_config_free(spawnConfigHandle);
                winpty_error_free(errorHandle);
            }

            var port = Utilities.GetAvailablePort();

            if (port == null)
            {
                throw new Exception("no port available");
            }

            Id = port.Value;

            ListenToStdOut();
        }
        public async Task <CreateTerminalResponse> CreateTerminal(TerminalSize size, ShellProfile shellProfile)
        {
            var request = new CreateTerminalRequest
            {
                Size    = size,
                Profile = shellProfile
            };

            var responseMessage = await _appServiceConnection.SendMessageAsync(CreateMessage(request));

            return(JsonConvert.DeserializeObject <CreateTerminalResponse>(responseMessage[MessageKeys.Content]));
        }
예제 #7
0
        public void Start(CreateTerminalRequest request, TerminalsManager terminalsManager)
        {
            Id = request.Id;
            _terminalsManager = terminalsManager;

            var configHandle      = IntPtr.Zero;
            var spawnConfigHandle = IntPtr.Zero;
            var errorHandle       = IntPtr.Zero;

            try
            {
                configHandle = winpty_config_new(WINPTY_FLAG_COLOR_ESCAPES, out errorHandle);
                winpty_config_set_initial_size(configHandle, request.Size.Columns, request.Size.Rows);

                _handle = winpty_open(configHandle, out errorHandle);
                if (errorHandle != IntPtr.Zero)
                {
                    throw new Exception(winpty_error_msg(errorHandle));
                }

                string exe  = request.Profile.Location;
                string args = $"\"{exe}\" {request.Profile.Arguments}";
                string cwd  = GetWorkingDirectory(request.Profile);
                spawnConfigHandle = winpty_spawn_config_new(WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN, exe, args, cwd, null, out errorHandle);
                if (errorHandle != IntPtr.Zero)
                {
                    throw new Exception(winpty_error_msg(errorHandle));
                }

                _stdin  = CreatePipe(winpty_conin_name(_handle), PipeDirection.Out);
                _stdout = CreatePipe(winpty_conout_name(_handle), PipeDirection.In);

                if (!winpty_spawn(_handle, spawnConfigHandle, out IntPtr process, out IntPtr thread, out int procError, out errorHandle))
                {
                    throw new Exception($"Failed to start the shell process. Please check your shell settings.\nTried to start: {args}");
                }

                var shellProcessId = ProcessApi.GetProcessId(process);
                _shellProcess = Process.GetProcessById(shellProcessId);
                _shellProcess.EnableRaisingEvents = true;
                _shellProcess.Exited += _shellProcess_Exited;

                ShellExecutableName = Path.GetFileNameWithoutExtension(exe);
            }
            finally
            {
                winpty_config_free(configHandle);
                winpty_spawn_config_free(spawnConfigHandle);
                winpty_error_free(errorHandle);
            }

            ListenToStdOut();
        }
예제 #8
0
        public CreateTerminalResponse CreateTerminal(CreateTerminalRequest request)
        {
            if (_terminals.ContainsKey(request.Id))
            {
                // App terminated without cleaning up, removing orphaned sessions
                foreach (var item in _terminals.Values)
                {
                    item.Dispose();
                }
                _terminals.Clear();
            }

            string error = request.Profile?.CheckIfMosh();

            if (!string.IsNullOrEmpty(error))
            {
                return(new CreateTerminalResponse
                {
                    Error = error, ShellExecutableName = request.Profile.Location, Success = false
                });
            }

            ITerminalSession terminal = null;

            try
            {
                if (request.SessionType == SessionType.WinPty)
                {
                    terminal = new WinPtySession();
                }
                else if (request.SessionType == SessionType.ConPty)
                {
                    terminal = new ConPtySession();
                }
                terminal.Start(request, this);
            }
            catch (Exception e)
            {
                return(new CreateTerminalResponse {
                    Error = e.ToString()
                });
            }

            terminal.ConnectionClosed += OnTerminalConnectionClosed;
            _terminals.Add(terminal.Id, terminal);
            return(new CreateTerminalResponse
            {
                Success = true,
                ShellExecutableName = terminal.ShellExecutableName
            });
        }
예제 #9
0
        public void Start(CreateTerminalRequest request, TerminalsManager terminalsManager)
        {
            Id = request.Id;
            _terminalsManager = terminalsManager;

            ShellExecutableName = Path.GetFileNameWithoutExtension(request.Profile.Location);
            var    cwd  = GetWorkingDirectory(request.Profile);
            string args = $"\"{request.Profile.Location}\" {request.Profile.Arguments}";

            _terminal              = new Terminal();
            _terminal.OutputReady += _terminal_OutputReady;
            _terminal.Exited      += _terminal_Exited;
            Task.Run(() => _terminal.Start(args, cwd, request.Size.Columns, request.Size.Rows));
        }
        public CreateTerminalResponse CreateTerminal(CreateTerminalRequest request)
        {
            if (_terminals.ContainsKey(request.Id))
            {
                // App terminated without cleaning up, removing orphaned sessions
                foreach (var item in _terminals.Values)
                {
                    item.Session.Dispose();
                }
                _terminals.Clear();
            }

            request.Profile.Location = Utilities.ResolveLocation(request.Profile.Location);

            ITerminalSession terminal = null;

            try
            {
                if (request.SessionType == SessionType.WinPty)
                {
                    terminal = new WinPtySession();
                }
                else
                {
                    terminal = new ConPtySession();
                }
                terminal.Start(request, this);
            }
            catch (Exception e)
            {
                return(new CreateTerminalResponse {
                    Error = e.ToString()
                });
            }

            var name = string.IsNullOrEmpty(request.Profile.Name) ? terminal.ShellExecutableName : request.Profile.Name;

            terminal.ConnectionClosed += OnTerminalConnectionClosed;
            _terminals.Add(terminal.Id, new TerminalSessionInfo
            {
                ProfileName = name,
                StartTime   = DateTime.Now,
                Session     = terminal
            });
            return(new CreateTerminalResponse
            {
                Success = true,
                Name = name
            });
        }
        public async Task <CreateTerminalResponse> CreateTerminal(TerminalSize size, ShellProfile shellProfile)
        {
            var request = new CreateTerminalRequest
            {
                Size    = size,
                Profile = shellProfile
            };

            var message = new ValueSet
            {
                { MessageKeys.Type, MessageTypes.CreateTerminalRequest },
                { MessageKeys.Content, JsonConvert.SerializeObject(request) }
            };

            var responseMessage = await _appServiceConnection.SendMessageAsync(message);

            return(JsonConvert.DeserializeObject <CreateTerminalResponse>((string)responseMessage.Message[MessageKeys.Content]));
        }
        public async Task <CreateTerminalResponse> CreateTerminalAsync(byte id, TerminalSize size, ShellProfile shellProfile,
                                                                       SessionType sessionType)
        {
            var request = new CreateTerminalRequest
            {
                Id          = id,
                Size        = size,
                Profile     = shellProfile,
                SessionType = sessionType
            };

            Logger.Instance.Debug("Sending CreateTerminalRequest: {@request}", request);

            var response = await GetResponseAsync <CreateTerminalResponse>(request).ConfigureAwait(false);

            Logger.Instance.Debug("Received CreateTerminalResponse: {@response}", response);

            return(response);
        }
        public async Task <CreateTerminalResponse> CreateTerminal(byte id, TerminalSize size, ShellProfile shellProfile, SessionType sessionType)
        {
            var request = new CreateTerminalRequest
            {
                Id          = id,
                Size        = size,
                Profile     = shellProfile,
                SessionType = sessionType
            };

            Logger.Instance.Debug("Sending CreateTerminalRequest: {@request}", request);

            var responseMessage = await _appServiceConnection.SendMessageAsync(CreateMessage(request));

            var response = JsonConvert.DeserializeObject <CreateTerminalResponse>((string)responseMessage[MessageKeys.Content]);

            Logger.Instance.Debug("Received CreateTerminalResponse: {@response}", response);

            return(response);
        }
예제 #14
0
        public void Start(CreateTerminalRequest request, TerminalsManager terminalsManager)
        {
            _terminalsManager = terminalsManager;

            var port = Utilities.GetAvailablePort();

            if (port == null)
            {
                throw new Exception("no port available");
            }

            Id = port.Value;
            ShellExecutableName = Path.GetFileNameWithoutExtension(request.Profile.Location);
            var    cwd  = GetWorkingDirectory(request.Profile);
            string args = $"\"{request.Profile.Location}\" {request.Profile.Arguments}";

            _terminal              = new Terminal();
            _terminal.OutputReady += _terminal_OutputReady;
            _terminal.Exited      += _terminal_Exited;
            Task.Run(() => _terminal.Start(args, cwd, request.Size.Columns, request.Size.Rows));
        }
예제 #15
0
        public void Start(CreateTerminalRequest request, TerminalsManager terminalsManager)
        {
            Id = request.Id;
            _terminalsManager = terminalsManager;
            _terminalSize     = request.Size;

            var configHandle      = IntPtr.Zero;
            var spawnConfigHandle = IntPtr.Zero;
            var errorHandle       = IntPtr.Zero;

            try
            {
                configHandle = winpty_config_new(WINPTY_FLAG_COLOR_ESCAPES, out errorHandle);
                winpty_config_set_initial_size(configHandle, request.Size.Columns, request.Size.Rows);

                _handle = winpty_open(configHandle, out errorHandle);
                if (errorHandle != IntPtr.Zero)
                {
                    throw new Exception(winpty_error_msg(errorHandle));
                }

                var cwd  = GetWorkingDirectory(request.Profile);
                var args = request.Profile.Arguments;

                if (!string.IsNullOrWhiteSpace(request.Profile.Location))
                {
                    args = $"\"{request.Profile.Location}\" {args}";
                }

                spawnConfigHandle = winpty_spawn_config_new(WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN, request.Profile.Location, args, cwd, terminalsManager.GetDefaultEnvironmentVariableString(request.Profile.EnvironmentVariables), out errorHandle);
                if (errorHandle != IntPtr.Zero)
                {
                    throw new Exception(winpty_error_msg(errorHandle));
                }

                _stdin  = CreatePipe(winpty_conin_name(_handle), PipeDirection.Out);
                _stdout = CreatePipe(winpty_conout_name(_handle), PipeDirection.In);

                if (!winpty_spawn(_handle, spawnConfigHandle, out IntPtr process, out IntPtr thread, out int procError, out errorHandle))
                {
                    throw new Exception($@"Failed to start the shell process. Please check your shell settings.{Environment.NewLine}Tried to start: {request.Profile.Location} ""{request.Profile.Arguments}""");
                }

                var shellProcessId = ProcessApi.GetProcessId(process);
                _shellProcess = Process.GetProcessById(shellProcessId);
                _shellProcess.EnableRaisingEvents = true;
                _shellProcess.Exited += _shellProcess_Exited;

                if (!string.IsNullOrWhiteSpace(request.Profile.Location))
                {
                    ShellExecutableName = Path.GetFileNameWithoutExtension(request.Profile.Location);
                }
                else
                {
                    ShellExecutableName = request.Profile.Arguments.Split(' ')[0];
                }
            }
            finally
            {
                winpty_config_free(configHandle);
                winpty_spawn_config_free(spawnConfigHandle);
                winpty_error_free(errorHandle);
            }

            ListenToStdOut();
        }
예제 #16
0
        public TerminalSession(CreateTerminalRequest request)
        {
            var configHandle      = IntPtr.Zero;
            var spawnConfigHandle = IntPtr.Zero;
            var errorHandle       = IntPtr.Zero;

            try
            {
                configHandle = winpty_config_new(WINPTY_FLAG_COLOR_ESCAPES, out errorHandle);
                winpty_config_set_initial_size(configHandle, request.Size.Columns, request.Size.Rows);

                _handle = winpty_open(configHandle, out errorHandle);
                if (errorHandle != IntPtr.Zero)
                {
                    throw new Exception(winpty_error_msg(errorHandle).ToString());
                }

                string exe  = GetShellLocation(request.Configuration);
                string args = $"\"{exe}\" {request.Configuration.Arguments}";
                string cwd  = GetWorkingDirectory(request.Configuration);
                spawnConfigHandle = winpty_spawn_config_new(WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN, exe, args, cwd, null, out errorHandle);
                if (errorHandle != IntPtr.Zero)
                {
                    throw new Exception(winpty_error_msg(errorHandle).ToString());
                }

                _stdin  = CreatePipe(winpty_conin_name(_handle), PipeDirection.Out);
                _stdout = CreatePipe(winpty_conout_name(_handle), PipeDirection.In);

                if (!winpty_spawn(_handle, spawnConfigHandle, out IntPtr process, out IntPtr thread, out int procError, out errorHandle))
                {
                    throw new Exception($"Failed to start the shell process. Please check your shell settings.\nTried to start: {args}");
                }

                ShellExecutableName = Path.GetFileNameWithoutExtension(exe);
            }
            finally
            {
                winpty_config_free(configHandle);
                winpty_spawn_config_free(spawnConfigHandle);
                winpty_error_free(errorHandle);
            }

            var port = Utilities.GetAvailablePort();

            if (port == null)
            {
                throw new Exception("no port available");
            }

            Id = port.Value;
            _connectedEvent = new ManualResetEventSlim(false);
            WebSocketUrl    = "ws://127.0.0.1:" + port;
            var webSocketServer = new WebSocketServer(WebSocketUrl);

            webSocketServer.Start(socket =>
            {
                _webSocket    = socket;
                socket.OnOpen = () =>
                {
                    Console.WriteLine("open");
                    _connectedEvent.Set();
                };
                socket.OnClose = () =>
                {
                    Console.WriteLine("closing");
                    ConnectionClosed?.Invoke(this, EventArgs.Empty);
                };
                socket.OnMessage = message =>
                {
                    var bytes = Encoding.UTF8.GetBytes(message);
                    _stdin.Write(bytes, 0, bytes.Length);
                };
            });

            ListenToStdOut();
        }