private static ProcessInfo RunProcess(ref StartInfoExtended sInfoEx, string commandLine) { int securityAttributeSize = Marshal.SizeOf <SecurityAttributes>(); var pSec = new SecurityAttributes { nLength = securityAttributeSize }; var tSec = new SecurityAttributes { nLength = securityAttributeSize }; var success = ProcessApi.CreateProcess( lpApplicationName: null, lpCommandLine: commandLine, lpProcessAttributes: ref pSec, lpThreadAttributes: ref tSec, bInheritHandles: false, dwCreationFlags: Constants.EXTENDED_STARTUPINFO_PRESENT, lpEnvironment: IntPtr.Zero, lpCurrentDirectory: null, lpStartupInfo: ref sInfoEx, lpProcessInformation: out ProcessInfo pInfo ); if (!success) { throw InteropException.CreateWithInnerHResultException("Could not create process."); } return(pInfo); }
private static StartInfoExtended ConfigureProcessThread(IntPtr hPC, IntPtr attributes) { // this method implements the behavior described in https://docs.microsoft.com/en-us/windows/console/creating-a-pseudoconsole-session#preparing-for-creation-of-the-child-process var lpSize = IntPtr.Zero; var success = ProcessApi.InitializeProcThreadAttributeList( lpAttributeList: IntPtr.Zero, dwAttributeCount: 1, dwFlags: 0, lpSize: ref lpSize ); if (success || lpSize == IntPtr.Zero) // we're not expecting `success` here, we just want to get the calculated lpSize { throw InteropException.CreateWithInnerHResultException("Could not calculate the number of bytes for the attribute list."); } var startupInfo = new StartInfoExtended(); startupInfo.StartupInfo.cb = Marshal.SizeOf <StartInfoExtended>(); startupInfo.lpAttributeList = Marshal.AllocHGlobal(lpSize); success = ProcessApi.InitializeProcThreadAttributeList( lpAttributeList: startupInfo.lpAttributeList, dwAttributeCount: 1, dwFlags: 0, lpSize: ref lpSize ); if (!success) { throw InteropException.CreateWithInnerHResultException("Could not set up attribute list."); } success = ProcessApi.UpdateProcThreadAttribute( lpAttributeList: startupInfo.lpAttributeList, dwFlags: 0, attribute: attributes, lpValue: hPC, cbSize: (IntPtr)IntPtr.Size, lpPreviousValue: IntPtr.Zero, lpReturnSize: IntPtr.Zero ); if (!success) { throw InteropException.CreateWithInnerHResultException("Could not set pseudoconsole thread attribute."); } return(startupInfo); }
private static void SetConsoleModeToVirtualTerminal() { SafeFileHandle stdIn = ConsoleApi.GetStdHandle(StdHandle.InputHandle); if (!ConsoleApi.GetConsoleMode(stdIn, out uint outConsoleMode)) { throw InteropException.CreateWithInnerHResultException("Could not get console mode."); } outConsoleMode |= Constants.ENABLE_VIRTUAL_TERMINAL_PROCESSING | Constants.DISABLE_NEWLINE_AUTO_RETURN; if (!ConsoleApi.SetConsoleMode(stdIn, outConsoleMode)) { throw InteropException.CreateWithInnerHResultException("Could not enable virtual terminal processing."); } }
public static PseudoConsole Create(SafeFileHandle inputReadSide, SafeFileHandle outputWriteSide, short width, short height) { int createResult = ConPtyApi.CreatePseudoConsole( new Coordinates { X = width, Y = height }, inputReadSide, outputWriteSide, 0, out IntPtr hPC); if (createResult != 0) { throw InteropException.CreateWithInnerHResultException($"Could not create pseudo console. Error Code: {createResult}"); } return(new PseudoConsole(hPC)); }
private void MakeHandleNoninheritable(ref SafeFileHandle handler, IntPtr processHandle) { // Create noninheritable read handle and close the inheritable read handle. IntPtr handleClone; if (!ConsoleApi.DuplicateHandle( processHandle, handler.DangerousGetHandle(), processHandle, out handleClone, 0, false, Constants.DUPLICATE_SAME_ACCESS)) { throw InteropException.CreateWithInnerHResultException("Couldn't duplicate the handle."); } SafeFileHandle toRelease = handler; handler = new SafeFileHandle(handleClone, true); toRelease.Dispose(); }