Example #1
0
        public static ExecutionProfile Get()
        {
            var profile = new ExecutionProfile()
            {
                Command = GetDefaultCommand(),
                CurrentWorkingDirectory = GetDefaultWorkingDirectory()
            };

            return(profile);
        }
Example #2
0
        public NativePty(ExecutionProfile executionProfile, TerminalSize size)
        {
            SafeFileHandle stdin;
            SafeFileHandle stdout;

            CreatePipe(out stdin, out _writeHandle, IntPtr.Zero, 0);
            CreatePipe(out _readHandle, out stdout, IntPtr.Zero, 0);

            W32Throw(CreatePseudoConsole(new COORD {
                X = (short)size.Columns, Y = (short)size.Rows
            },
                                         stdin, stdout, 0, out this._ptyHandle));

            var allocSize = IntPtr.Zero;

            InitializeProcThreadAttributeList(IntPtr.Zero, 1, 0, ref allocSize);
            if (allocSize == IntPtr.Zero)
            {
                W32Throw(0, "allocation granularity whatever.");
            }

            var startupInfo = new STARTUPINFOEX
            {
                StartupInfo     = { cb = Marshal.SizeOf <STARTUPINFOEX>() },
                lpAttributeList = Marshal.AllocHGlobal(allocSize)
            };

            W32Throw(InitializeProcThreadAttributeList(startupInfo.lpAttributeList, 1, 0, ref allocSize));

            W32Throw(UpdateProcThreadAttribute(startupInfo.lpAttributeList, 0,
                                               (IntPtr)PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, _ptyHandle, (IntPtr)IntPtr.Size, IntPtr.Zero,
                                               IntPtr.Zero));

            var processSecurityAttr = new SECURITY_ATTRIBUTES();
            var threadSecurityAttr  = new SECURITY_ATTRIBUTES();

            processSecurityAttr.nLength = threadSecurityAttr.nLength = Marshal.SizeOf <SECURITY_ATTRIBUTES>();

            var args    = executionProfile.Arguments ?? Array.Empty <string>();
            var cmdline = executionProfile.EscapeArguments
                ? string.Join(" ", args.Select(x => $"\"{x}\""))
                : string.Join(" ", args);

            W32Throw(CreateProcess(executionProfile.Command, cmdline, ref processSecurityAttr, ref threadSecurityAttr,
                                   false, EXTENDED_STARTUPINFO_PRESENT, IntPtr.Zero, null, ref startupInfo, out var processInfo));

            DeleteProcThreadAttributeList(startupInfo.lpAttributeList);
            Marshal.FreeHGlobal(startupInfo.lpAttributeList);

            StandardOutput = new FileStream(_readHandle, FileAccess.Read);
            StandardInput  = new FileStream(_writeHandle, FileAccess.Write);
        }
Example #3
0
        public static ExecutionProfile ExpandVariables(this ExecutionProfile executionProfile)
        {
            var envHelper = new EnvironmentVariableHelper();
            var env       = envHelper.GetUser();

            var profileEnv = executionProfile.EnvironmentVariables;

            if (profileEnv != null)
            {
                envHelper.ExpandVariables(env, profileEnv);
            }

            return(new ExecutionProfile()
            {
                Command = envHelper.ExpandVariables(executionProfile.Command, env),
                CurrentWorkingDirectory = envHelper.ExpandVariables(executionProfile.CurrentWorkingDirectory, env),
                Arguments = executionProfile.Arguments?.Select(x => envHelper.ExpandVariables(x, env)).ToArray(),
                EnvironmentVariables = env
            });
        }
Example #4
0
        public WinPty(ExecutionProfile executionProfile, TerminalSize size, bool separateStdErr = false)
        {
            _size = size;

            IntPtr err      = IntPtr.Zero;
            IntPtr cfg      = IntPtr.Zero;
            IntPtr spawnCfg = IntPtr.Zero;

            try
            {
                ulong cfgFlags = WINPTY_FLAG_COLOR_ESCAPES;
                if (separateStdErr)
                {
                    cfgFlags |= WINPTY_FLAG_CONERR;
                }

                cfg = winpty_config_new(cfgFlags, out err);
                winpty_config_set_initial_size(cfg, size.Columns, size.Rows);

                _handle = winpty_open(cfg, out err);
                if (err != IntPtr.Zero)
                {
                    throw new WinPtrException(err);
                }

                string cmdline = null;
                string env     = GetEnvironmentString(executionProfile.EnvironmentVariables);
                if (executionProfile.Arguments != null && executionProfile.Arguments.Length > 0)
                {
                    cmdline = executionProfile.EscapeArguments
                        ? string.Join(" ", executionProfile.Arguments.Select(x => $"\"{x}\""))
                        : string.Join(" ", executionProfile.Arguments);
                }

                cmdline  = $"{executionProfile.Command} {cmdline}";
                spawnCfg = winpty_spawn_config_new(WINPTY_SPAWN_FLAG_AUTO_SHUTDOWN, executionProfile.Command, cmdline,
                                                   executionProfile.CurrentWorkingDirectory, env, out err);
                if (err != IntPtr.Zero)
                {
                    throw new WinPtrException(err);
                }

                StandardInput  = CreatePipe(winpty_conin_name(_handle), PipeDirection.Out);
                StandardOutput = CreatePipe(winpty_conout_name(_handle), PipeDirection.In);
                if (separateStdErr)
                {
                    StandardError = CreatePipe(winpty_conerr_name(_handle), PipeDirection.In);
                }

                if (!winpty_spawn(_handle, spawnCfg, out IntPtr process, out IntPtr thread, out int procError, out err))
                {
                    throw new WinPtrException(err);
                }
            }
            finally
            {
                winpty_config_free(cfg);
                winpty_spawn_config_free(spawnCfg);
                winpty_error_free(err);
            }
        }