Example #1
0
        public static InputWriterOnlyPseudoConsole Create()
        {
            var(inputReader, inputWriter) = FilePal.CreatePipePair();
            var outputWriter = FilePal.OpenNullDevice(FileAccess.Write);
            var hPC          = SafePseudoConsoleHandle.Create(inputReader, outputWriter);

            return(new InputWriterOnlyPseudoConsole(hPC, inputWriter));
        }
        private SafeFileHandle OpenNullDevice(FileAccess access)
        {
            EnsureObjectsToDispose();

            var handle = FilePal.OpenNullDevice(access);

            _objectsToDispose.Add(handle);
            return(handle);
        }
        private SafeFileHandle ChooseOutput(
            OutputRedirection redirection,
            string fileName,
            SafeFileHandle handle,
            SafeFileHandle outputPipe,
            SafeFileHandle errorPipe)
        {
            switch (redirection)
            {
            case OutputRedirection.ParentOutput:
                return(ConsolePal.GetStdOutputHandleForChild() ?? OpenNullDevice(FileAccess.Write));

            case OutputRedirection.ParentError:
                return(ConsolePal.GetStdErrorHandleForChild() ?? OpenNullDevice(FileAccess.Write));

            case OutputRedirection.OutputPipe:
                return(outputPipe);

            case OutputRedirection.ErrorPipe:
                return(errorPipe);

            case OutputRedirection.File:
                return(OpenFile(fileName, FileMode.Create, FileAccess.Write, FileShare.Read));

            case OutputRedirection.AppendToFile:
                return(OpenFile(fileName, FileMode.Append, FileAccess.Write, FileShare.Read));

            case OutputRedirection.Handle:
                return(handle);

            case OutputRedirection.NullDevice:
                return(FilePal.OpenNullDevice(FileAccess.Write));

            default:
                throw new ArgumentOutOfRangeException(nameof(redirection), "Not a valid value for " + nameof(OutputRedirection) + ".");
            }
        }
Example #4
0
 public SafeFileHandle GetStdErrorHandleForChild(bool createNewConsole) =>
 DuplicateStdFileForChild(StdErrFileNo, createNewConsole) ?? FilePal.OpenNullDevice(System.IO.FileAccess.Write);
Example #5
0
 public SafeFileHandle GetStdInputHandleForChild(bool createNewConsole) =>
 DuplicateStdFileForChild(StdInFileNo, createNewConsole) ?? FilePal.OpenNullDevice(System.IO.FileAccess.Read);
Example #6
0
 public SafeFileHandle GetStdErrorHandleForChild(bool createNewConsole) =>
 GetStdHandleForChild(Kernel32.STD_ERROR_HANDLE, createNewConsole) ?? FilePal.OpenNullDevice(System.IO.FileAccess.Write);
Example #7
0
 public SafeFileHandle GetStdInputHandleForChild(bool createNewConsole) =>
 GetStdHandleForChild(Kernel32.STD_INPUT_HANDLE, createNewConsole) ?? FilePal.OpenNullDevice(System.IO.FileAccess.Read);
Example #8
0
        // Change the code page of the specified pseudo console by invoking chcp.com on it.
        private static unsafe void ChangeCodePage(
            InputWriterOnlyPseudoConsole pseudoConsole,
            int codePage,
            string?workingDirectory)
        {
            var commandLine = new StringBuilder(ChcpPath.Length + 5);

            WindowsCommandLineUtil.AppendStringQuoted(commandLine, ChcpPath);
            commandLine.Append(' ');
            commandLine.Append(codePage.ToString(CultureInfo.InvariantCulture));

            using var inheritableHandleStore = new InheritableHandleStore(3);
            using var nullDevice             = FilePal.OpenNullDevice(FileAccess.ReadWrite);
            var childStdIn  = inheritableHandleStore.Add(nullDevice);
            var childStdOut = inheritableHandleStore.Add(nullDevice);
            var childStdErr = inheritableHandleStore.Add(nullDevice);

            SafeProcessHandle?processHandle = null;

            try
            {
                Span <IntPtr> inheritableHandles = stackalloc IntPtr[inheritableHandleStore.Count];
                inheritableHandleStore.DangerousGetHandles(inheritableHandles);
                fixed(IntPtr *pInheritableHandles = inheritableHandles)
                {
                    using var attr = new ProcThreadAttributeList(2);
                    attr.UpdatePseudoConsole(pseudoConsole.Handle.DangerousGetHandle());
                    attr.UpdateHandleList(pInheritableHandles, inheritableHandles.Length);

                    const int CreationFlags =
                        Kernel32.CREATE_UNICODE_ENVIRONMENT
                        | Kernel32.EXTENDED_STARTUPINFO_PRESENT;

                    SafeThreadHandle threadHandle;

                    (_, processHandle, threadHandle) = InvokeCreateProcess(
                        commandLine,
                        CreationFlags,
                        null,
                        workingDirectory,
                        childStdIn,
                        childStdOut,
                        childStdErr,
                        attr);
                    threadHandle.Dispose();
                }

                using var waitHandle = new WindowsProcessWaitHandle(processHandle);
                waitHandle.WaitOne();

                if (!Kernel32.GetExitCodeProcess(processHandle, out var exitCode))
                {
                    throw new Win32Exception();
                }

                if (exitCode != 0)
                {
                    ThrowHelper.ThrowChcpFailedException(codePage, exitCode, nameof(codePage));
                }
            }
            finally
            {
                processHandle?.Dispose();
            }
        }