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) + "."); } }
public SafeFileHandle GetStdErrorHandleForChild(bool createNewConsole) => DuplicateStdFileForChild(StdErrFileNo, createNewConsole) ?? FilePal.OpenNullDevice(System.IO.FileAccess.Write);
public SafeFileHandle GetStdInputHandleForChild(bool createNewConsole) => DuplicateStdFileForChild(StdInFileNo, createNewConsole) ?? FilePal.OpenNullDevice(System.IO.FileAccess.Read);
public SafeFileHandle GetStdErrorHandleForChild(bool createNewConsole) => GetStdHandleForChild(Kernel32.STD_ERROR_HANDLE, createNewConsole) ?? FilePal.OpenNullDevice(System.IO.FileAccess.Write);
public SafeFileHandle GetStdInputHandleForChild(bool createNewConsole) => GetStdHandleForChild(Kernel32.STD_INPUT_HANDLE, createNewConsole) ?? FilePal.OpenNullDevice(System.IO.FileAccess.Read);
// 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(); } }