@@ -455,16 +455,13 @@ private unsafe bool StartWithCreateProcess(ProcessStartInfo startInfo, SafeFileH
455455 {
456456 Debug . Assert ( stdinHandle is not null && stdoutHandle is not null && stderrHandle is not null , "All or none of the standard handles must be provided." ) ;
457457
458- // The user can't specify invalid handle via ProcessStartInfo.Standar*Handle APIs.
459- // However, Console.OpenStandard*Handle() can return INVALID_HANDLE_VALUE for a process
460- // that was started with INVALID_HANDLE_VALUE as given standard handle.
461- inheritableStdinHandle = ! stdinHandle . IsInvalid && ! stdinHandle . IsInheritable ( ) ? DuplicateAsInheritable ( stdinHandle ) : stdinHandle ;
462- inheritableStdoutHandle = ! stdoutHandle . IsInvalid && ! stdoutHandle . IsInheritable ( ) ? DuplicateAsInheritable ( stdoutHandle ) : stdoutHandle ;
463- inheritableStderrHandle = ! stderrHandle . IsInvalid && ! stderrHandle . IsInheritable ( ) ? DuplicateAsInheritable ( stderrHandle ) : stderrHandle ;
458+ DuplicateAsInheritableIfNeeded ( stdinHandle , out inheritableStdinHandle ) ;
459+ DuplicateAsInheritableIfNeeded ( stdoutHandle , out inheritableStdoutHandle ) ;
460+ DuplicateAsInheritableIfNeeded ( stderrHandle , out inheritableStderrHandle ) ;
464461
465- startupInfo . hStdInput = inheritableStdinHandle . DangerousGetHandle ( ) ;
466- startupInfo . hStdOutput = inheritableStdoutHandle . DangerousGetHandle ( ) ;
467- startupInfo . hStdError = inheritableStderrHandle . DangerousGetHandle ( ) ;
462+ startupInfo . hStdInput = ( inheritableStdinHandle ?? stdinHandle ) . DangerousGetHandle ( ) ;
463+ startupInfo . hStdOutput = ( inheritableStdoutHandle ?? stdoutHandle ) . DangerousGetHandle ( ) ;
464+ startupInfo . hStdError = ( inheritableStderrHandle ?? stderrHandle ) . DangerousGetHandle ( ) ;
468465
469466 // If STARTF_USESTDHANDLES is not set, the new process will inherit the standard handles.
470467 startupInfo . dwFlags = Interop . Advapi32 . StartupInfoOptions . STARTF_USESTDHANDLES ;
@@ -598,12 +595,9 @@ ref processInfo // pointer to PROCESS_INFORMATION
598595 {
599596 // Only dispose duplicated handles, not the original handles passed by the caller.
600597 // When the handle was invalid or already inheritable, no duplication was needed.
601- if ( ! ReferenceEquals ( inheritableStdinHandle , stdinHandle ) )
602- inheritableStdinHandle ? . Dispose ( ) ;
603- if ( ! ReferenceEquals ( inheritableStdoutHandle , stdoutHandle ) )
604- inheritableStdoutHandle ? . Dispose ( ) ;
605- if ( ! ReferenceEquals ( inheritableStderrHandle , stderrHandle ) )
606- inheritableStderrHandle ? . Dispose ( ) ;
598+ inheritableStdinHandle ? . Dispose ( ) ;
599+ inheritableStdoutHandle ? . Dispose ( ) ;
600+ inheritableStderrHandle ? . Dispose ( ) ;
607601
608602 ProcessUtils . s_processStartLock . ExitWriteLock ( ) ;
609603
@@ -621,21 +615,29 @@ ref processInfo // pointer to PROCESS_INFORMATION
621615 return true ;
622616 }
623617
624- /// <summary>Duplicates a handle as inheritable so the child process can use it .</summary>
625- private static SafeFileHandle DuplicateAsInheritable ( SafeFileHandle sourceHandle )
618+ /// <summary>Duplicates a handle as inheritable if it's valid and not inheritable .</summary>
619+ private static void DuplicateAsInheritableIfNeeded ( SafeFileHandle sourceHandle , out SafeFileHandle ? duplicatedHandle )
626620 {
621+ // The user can't specify invalid handle via ProcessStartInfo.Standar*Handle APIs.
622+ // However, Console.OpenStandard*Handle() can return INVALID_HANDLE_VALUE for a process
623+ // that was started with INVALID_HANDLE_VALUE as given standard handle.
624+ if ( sourceHandle . IsInvalid || sourceHandle . IsInheritable ( ) )
625+ {
626+ duplicatedHandle = null ;
627+ return ;
628+ }
629+
627630 IntPtr currentProcHandle = Interop . Kernel32 . GetCurrentProcess ( ) ;
628631 if ( ! Interop . Kernel32 . DuplicateHandle ( currentProcHandle ,
629632 sourceHandle ,
630633 currentProcHandle ,
631- out SafeFileHandle duplicatedHandle ,
634+ out duplicatedHandle ,
632635 0 ,
633636 bInheritHandle : true ,
634637 Interop . Kernel32 . HandleOptions . DUPLICATE_SAME_ACCESS ) )
635638 {
636639 throw new Win32Exception ( Marshal . GetLastWin32Error ( ) ) ;
637640 }
638- return duplicatedHandle ;
639641 }
640642
641643 private static ConsoleEncoding GetEncoding ( int codePage )
0 commit comments