internal static extern unsafe bool CreateProcessWithLogonW( string userName, string domain, IntPtr password, LogonFlags logonFlags, string?appName, char *cmdLine, int creationFlags, IntPtr environmentBlock, string?lpCurrentDirectory, ref Interop.Kernel32.STARTUPINFO lpStartupInfo, ref Interop.Kernel32.PROCESS_INFORMATION lpProcessInformation);
internal static extern bool CreateProcessWithLogonW( string userName, string domain, string passwordInClearText, LogonFlags logonFlags, [MarshalAs(UnmanagedType.LPTStr)] string appName, StringBuilder cmdLine, int creationFlags, IntPtr environmentBlock, [MarshalAs(UnmanagedType.LPTStr)] string lpCurrentDirectory, Interop.Kernel32.STARTUPINFO lpStartupInfo, Interop.Kernel32.PROCESS_INFORMATION lpProcessInformation);
public static extern bool DetourCreateProcessWithDllExA( string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref Interop.Kernel32.STARTUPINFO lpStartupInfo, out Interop.Kernel32.PROCESS_INFORMATION lpProcessInformation, string lpDllName, IntPtr pfCreateProcessA);
internal static extern bool CreateProcessWithLogonW( string userName, string domain, IntPtr password, LogonFlags logonFlags, string?appName, #pragma warning disable CA1838 // reasonable use of StringBuilder to build up a command line [In] StringBuilder cmdLine, #pragma warning restore CA1838 int creationFlags, IntPtr environmentBlock, string lpCurrentDirectory, ref Interop.Kernel32.STARTUPINFO lpStartupInfo, ref Interop.Kernel32.PROCESS_INFORMATION lpProcessInformation);
public static bool DetourCreateProcessWithDllsExW( string lpApplicationName, string lpCommandLine, IntPtr lpProcessAttributes, IntPtr lpThreadAttributes, bool bInheritHandles, uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, ref Interop.Kernel32.STARTUPINFO lpStartupInfo, out Interop.Kernel32.PROCESS_INFORMATION lpProcessInformation, uint nDlls, IntPtr rlpDlls, IntPtr pfCreateProcessW) { if (Is64Bit) { return(NativeApi64.DetourCreateProcessWithDllsExW(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, ref lpStartupInfo, out lpProcessInformation, nDlls, rlpDlls, pfCreateProcessW)); } else { return(NativeApi32.DetourCreateProcessWithDllsExW(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, ref lpStartupInfo, out lpProcessInformation, nDlls, rlpDlls, pfCreateProcessW)); } }
/// <summary>Starts the process using the supplied start info.</summary> /// <param name="startInfo">The start info with which to start the process.</param> private unsafe bool StartWithCreateProcess(ProcessStartInfo startInfo) { // See knowledge base article Q190351 for an explanation of the following code. Noteworthy tricky points: // * The handles are duplicated as non-inheritable before they are passed to CreateProcess so // that the child process can not close them // * CreateProcess allows you to redirect all or none of the standard IO handles, so we use // GetStdHandle for the handles that are not being redirected StringBuilder commandLine = BuildCommandLine(startInfo.FileName, StartInfo.Arguments); Process.AppendArguments(commandLine, StartInfo.ArgumentList); Interop.Kernel32.STARTUPINFO startupInfo = new Interop.Kernel32.STARTUPINFO(); Interop.Kernel32.PROCESS_INFORMATION processInfo = new Interop.Kernel32.PROCESS_INFORMATION(); Interop.Kernel32.SECURITY_ATTRIBUTES unused_SecAttrs = new Interop.Kernel32.SECURITY_ATTRIBUTES(); SafeProcessHandle procSH = new SafeProcessHandle(); SafeThreadHandle threadSH = new SafeThreadHandle(); // handles used in parent process SafeFileHandle parentInputPipeHandle = null; SafeFileHandle childInputPipeHandle = null; SafeFileHandle parentOutputPipeHandle = null; SafeFileHandle childOutputPipeHandle = null; SafeFileHandle parentErrorPipeHandle = null; SafeFileHandle childErrorPipeHandle = null; lock (s_createProcessLock) { try { startupInfo.cb = sizeof(Interop.Kernel32.STARTUPINFO); // set up the streams if (startInfo.RedirectStandardInput || startInfo.RedirectStandardOutput || startInfo.RedirectStandardError) { if (startInfo.RedirectStandardInput) { CreatePipe(out parentInputPipeHandle, out childInputPipeHandle, true); } else { childInputPipeHandle = new SafeFileHandle(Interop.Kernel32.GetStdHandle(Interop.Kernel32.HandleTypes.STD_INPUT_HANDLE), false); } if (startInfo.RedirectStandardOutput) { CreatePipe(out parentOutputPipeHandle, out childOutputPipeHandle, false); } else { childOutputPipeHandle = new SafeFileHandle(Interop.Kernel32.GetStdHandle(Interop.Kernel32.HandleTypes.STD_OUTPUT_HANDLE), false); } if (startInfo.RedirectStandardError) { CreatePipe(out parentErrorPipeHandle, out childErrorPipeHandle, false); } else { childErrorPipeHandle = new SafeFileHandle(Interop.Kernel32.GetStdHandle(Interop.Kernel32.HandleTypes.STD_ERROR_HANDLE), false); } startupInfo.hStdInput = childInputPipeHandle.DangerousGetHandle(); startupInfo.hStdOutput = childOutputPipeHandle.DangerousGetHandle(); startupInfo.hStdError = childErrorPipeHandle.DangerousGetHandle(); startupInfo.dwFlags = Interop.Advapi32.StartupInfoOptions.STARTF_USESTDHANDLES; } // set up the creation flags parameter int creationFlags = 0; if (startInfo.CreateNoWindow) { creationFlags |= Interop.Advapi32.StartupInfoOptions.CREATE_NO_WINDOW; } // set up the environment block parameter string environmentBlock = null; if (startInfo._environmentVariables != null) { creationFlags |= Interop.Advapi32.StartupInfoOptions.CREATE_UNICODE_ENVIRONMENT; environmentBlock = GetEnvironmentVariablesBlock(startInfo._environmentVariables); } string workingDirectory = startInfo.WorkingDirectory; if (workingDirectory == string.Empty) { workingDirectory = Directory.GetCurrentDirectory(); } bool retVal; int errorCode = 0; if (startInfo.UserName.Length != 0) { if (startInfo.Password != null && startInfo.PasswordInClearText != null) { throw new ArgumentException(SR.CantSetDuplicatePassword); } Interop.Advapi32.LogonFlags logonFlags = (Interop.Advapi32.LogonFlags) 0; if (startInfo.LoadUserProfile) { logonFlags = Interop.Advapi32.LogonFlags.LOGON_WITH_PROFILE; } fixed(char *passwordInClearTextPtr = startInfo.PasswordInClearText ?? string.Empty) fixed(char *environmentBlockPtr = environmentBlock) { IntPtr passwordPtr = (startInfo.Password != null) ? Marshal.SecureStringToGlobalAllocUnicode(startInfo.Password) : IntPtr.Zero; try { retVal = Interop.Advapi32.CreateProcessWithLogonW( startInfo.UserName, startInfo.Domain, (passwordPtr != IntPtr.Zero) ? passwordPtr : (IntPtr)passwordInClearTextPtr, logonFlags, null, // we don't need this since all the info is in commandLine commandLine, creationFlags, (IntPtr)environmentBlockPtr, workingDirectory, ref startupInfo, // pointer to STARTUPINFO ref processInfo // pointer to PROCESS_INFORMATION ); if (!retVal) { errorCode = Marshal.GetLastWin32Error(); } } finally { if (passwordPtr != IntPtr.Zero) { Marshal.ZeroFreeGlobalAllocUnicode(passwordPtr); } } } } else { fixed(char *environmentBlockPtr = environmentBlock) { retVal = Interop.Kernel32.CreateProcess( null, // we don't need this since all the info is in commandLine commandLine, // pointer to the command line string ref unused_SecAttrs, // address to process security attributes, we don't need to inherit the handle ref unused_SecAttrs, // address to thread security attributes. true, // handle inheritance flag creationFlags, // creation flags (IntPtr)environmentBlockPtr, // pointer to new environment block workingDirectory, // pointer to current directory name ref startupInfo, // pointer to STARTUPINFO ref processInfo // pointer to PROCESS_INFORMATION ); if (!retVal) { errorCode = Marshal.GetLastWin32Error(); } } } if (processInfo.hProcess != IntPtr.Zero && processInfo.hProcess != new IntPtr(-1)) { procSH.InitialSetHandle(processInfo.hProcess); } if (processInfo.hThread != IntPtr.Zero && processInfo.hThread != new IntPtr(-1)) { threadSH.InitialSetHandle(processInfo.hThread); } if (!retVal) { if (errorCode == Interop.Errors.ERROR_BAD_EXE_FORMAT || errorCode == Interop.Errors.ERROR_EXE_MACHINE_TYPE_MISMATCH) { throw new Win32Exception(errorCode, SR.InvalidApplication); } throw new Win32Exception(errorCode); } } finally { childInputPipeHandle?.Dispose(); childOutputPipeHandle?.Dispose(); childErrorPipeHandle?.Dispose(); threadSH?.Dispose(); } } if (startInfo.RedirectStandardInput) { Encoding enc = startInfo.StandardInputEncoding ?? GetEncoding((int)Interop.Kernel32.GetConsoleCP()); _standardInput = new StreamWriter(new FileStream(parentInputPipeHandle, FileAccess.Write, 4096, false), enc, 4096); _standardInput.AutoFlush = true; } if (startInfo.RedirectStandardOutput) { Encoding enc = startInfo.StandardOutputEncoding ?? GetEncoding((int)Interop.Kernel32.GetConsoleOutputCP()); _standardOutput = new StreamReader(new FileStream(parentOutputPipeHandle, FileAccess.Read, 4096, false), enc, true, 4096); } if (startInfo.RedirectStandardError) { Encoding enc = startInfo.StandardErrorEncoding ?? GetEncoding((int)Interop.Kernel32.GetConsoleOutputCP()); _standardError = new StreamReader(new FileStream(parentErrorPipeHandle, FileAccess.Read, 4096, false), enc, true, 4096); } if (procSH.IsInvalid) { return(false); } SetProcessHandle(procSH); SetProcessId((int)processInfo.dwProcessId); return(true); }
/// <summary>Starts the process using the supplied start info.</summary> /// <param name="startInfo">The start info with which to start the process.</param> private bool StartCore(ProcessStartInfo startInfo) { // See knowledge base article Q190351 for an explanation of the following code. Noteworthy tricky points: // * The handles are duplicated as non-inheritable before they are passed to CreateProcess so // that the child process can not close them // * CreateProcess allows you to redirect all or none of the standard IO handles, so we use // GetStdHandle for the handles that are not being redirected StringBuilder commandLine = BuildCommandLine(startInfo.FileName, startInfo.Arguments); Interop.Kernel32.STARTUPINFO startupInfo = new Interop.Kernel32.STARTUPINFO(); Interop.Kernel32.PROCESS_INFORMATION processInfo = new Interop.Kernel32.PROCESS_INFORMATION(); Interop.Kernel32.SECURITY_ATTRIBUTES unused_SecAttrs = new Interop.Kernel32.SECURITY_ATTRIBUTES(); SafeProcessHandle procSH = new SafeProcessHandle(); SafeThreadHandle threadSH = new SafeThreadHandle(); bool retVal; int errorCode = 0; // handles used in parent process SafeFileHandle standardInputWritePipeHandle = null; SafeFileHandle standardOutputReadPipeHandle = null; SafeFileHandle standardErrorReadPipeHandle = null; GCHandle environmentHandle = new GCHandle(); lock (s_createProcessLock) { try { // set up the streams if (startInfo.RedirectStandardInput || startInfo.RedirectStandardOutput || startInfo.RedirectStandardError) { if (startInfo.RedirectStandardInput) { CreatePipe(out standardInputWritePipeHandle, out startupInfo.hStdInput, true); } else { startupInfo.hStdInput = new SafeFileHandle(Interop.Kernel32.GetStdHandle(Interop.Kernel32.HandleTypes.STD_INPUT_HANDLE), false); } if (startInfo.RedirectStandardOutput) { CreatePipe(out standardOutputReadPipeHandle, out startupInfo.hStdOutput, false); } else { startupInfo.hStdOutput = new SafeFileHandle(Interop.Kernel32.GetStdHandle(Interop.Kernel32.HandleTypes.STD_OUTPUT_HANDLE), false); } if (startInfo.RedirectStandardError) { CreatePipe(out standardErrorReadPipeHandle, out startupInfo.hStdError, false); } else { startupInfo.hStdError = new SafeFileHandle(Interop.Kernel32.GetStdHandle(Interop.Kernel32.HandleTypes.STD_ERROR_HANDLE), false); } startupInfo.dwFlags = Interop.Advapi32.StartupInfoOptions.STARTF_USESTDHANDLES; } // set up the creation flags parameter int creationFlags = 0; if (startInfo.CreateNoWindow) { creationFlags |= Interop.Advapi32.StartupInfoOptions.CREATE_NO_WINDOW; } // set up the environment block parameter IntPtr environmentPtr = (IntPtr)0; if (startInfo._environmentVariables != null) { creationFlags |= Interop.Advapi32.StartupInfoOptions.CREATE_UNICODE_ENVIRONMENT; byte[] environmentBytes = EnvironmentVariablesToByteArray(startInfo._environmentVariables); environmentHandle = GCHandle.Alloc(environmentBytes, GCHandleType.Pinned); environmentPtr = environmentHandle.AddrOfPinnedObject(); } string workingDirectory = startInfo.WorkingDirectory; if (workingDirectory == string.Empty) { workingDirectory = Directory.GetCurrentDirectory(); } if (startInfo.UserName.Length != 0) { Interop.Advapi32.LogonFlags logonFlags = (Interop.Advapi32.LogonFlags) 0; if (startInfo.LoadUserProfile) { logonFlags = Interop.Advapi32.LogonFlags.LOGON_WITH_PROFILE; } try { } finally { retVal = Interop.Advapi32.CreateProcessWithLogonW( startInfo.UserName, startInfo.Domain, startInfo.PasswordInClearText, logonFlags, null, // we don't need this since all the info is in commandLine commandLine, creationFlags, environmentPtr, workingDirectory, startupInfo, // pointer to STARTUPINFO processInfo // pointer to PROCESS_INFORMATION ); if (!retVal) { errorCode = Marshal.GetLastWin32Error(); } if (processInfo.hProcess != IntPtr.Zero && processInfo.hProcess != (IntPtr)INVALID_HANDLE_VALUE) { procSH.InitialSetHandle(processInfo.hProcess); } if (processInfo.hThread != IntPtr.Zero && processInfo.hThread != (IntPtr)INVALID_HANDLE_VALUE) { threadSH.InitialSetHandle(processInfo.hThread); } } if (!retVal) { if (errorCode == Interop.Errors.ERROR_BAD_EXE_FORMAT || errorCode == Interop.Errors.ERROR_EXE_MACHINE_TYPE_MISMATCH) { throw new Win32Exception(errorCode, SR.InvalidApplication); } throw new Win32Exception(errorCode); } } else { try { } finally { retVal = Interop.Kernel32.CreateProcess( null, // we don't need this since all the info is in commandLine commandLine, // pointer to the command line string ref unused_SecAttrs, // address to process security attributes, we don't need to inherit the handle ref unused_SecAttrs, // address to thread security attributes. true, // handle inheritance flag creationFlags, // creation flags environmentPtr, // pointer to new environment block workingDirectory, // pointer to current directory name startupInfo, // pointer to STARTUPINFO processInfo // pointer to PROCESS_INFORMATION ); if (!retVal) { errorCode = Marshal.GetLastWin32Error(); } if (processInfo.hProcess != (IntPtr)0 && processInfo.hProcess != (IntPtr)INVALID_HANDLE_VALUE) { procSH.InitialSetHandle(processInfo.hProcess); } if (processInfo.hThread != (IntPtr)0 && processInfo.hThread != (IntPtr)INVALID_HANDLE_VALUE) { threadSH.InitialSetHandle(processInfo.hThread); } } if (!retVal) { if (errorCode == Interop.Errors.ERROR_BAD_EXE_FORMAT || errorCode == Interop.Errors.ERROR_EXE_MACHINE_TYPE_MISMATCH) { throw new Win32Exception(errorCode, SR.InvalidApplication); } throw new Win32Exception(errorCode); } } } finally { // free environment block if (environmentHandle.IsAllocated) { environmentHandle.Free(); } startupInfo.Dispose(); } } if (startInfo.RedirectStandardInput) { Encoding enc = GetEncoding((int)Interop.Kernel32.GetConsoleCP()); _standardInput = new StreamWriter(new FileStream(standardInputWritePipeHandle, FileAccess.Write, 4096, false), enc, 4096); _standardInput.AutoFlush = true; } if (startInfo.RedirectStandardOutput) { Encoding enc = startInfo.StandardOutputEncoding ?? GetEncoding((int)Interop.Kernel32.GetConsoleOutputCP()); _standardOutput = new StreamReader(new FileStream(standardOutputReadPipeHandle, FileAccess.Read, 4096, false), enc, true, 4096); } if (startInfo.RedirectStandardError) { Encoding enc = startInfo.StandardErrorEncoding ?? GetEncoding((int)Interop.Kernel32.GetConsoleOutputCP()); _standardError = new StreamReader(new FileStream(standardErrorReadPipeHandle, FileAccess.Read, 4096, false), enc, true, 4096); } bool ret = false; if (!procSH.IsInvalid) { SetProcessHandle(procSH); SetProcessId((int)processInfo.dwProcessId); threadSH.Dispose(); ret = true; } return(ret); }
/// <summary>Starts the process using the supplied start info.</summary> /// <param name="startInfo">The start info with which to start the process.</param> private bool StartCore(ProcessStartInfo startInfo) { // See knowledge base article Q190351 for an explanation of the following code. Noteworthy tricky points: // * The handles are duplicated as non-inheritable before they are passed to CreateProcess so // that the child process can not close them // * CreateProcess allows you to redirect all or none of the standard IO handles, so we use // GetStdHandle for the handles that are not being redirected StringBuilder commandLine = BuildCommandLine(startInfo.FileName, startInfo.Arguments); Interop.Kernel32.STARTUPINFO startupInfo = new Interop.Kernel32.STARTUPINFO(); Interop.Kernel32.PROCESS_INFORMATION processInfo = new Interop.Kernel32.PROCESS_INFORMATION(); Interop.Kernel32.SECURITY_ATTRIBUTES unused_SecAttrs = new Interop.Kernel32.SECURITY_ATTRIBUTES(); SafeProcessHandle procSH = new SafeProcessHandle(); SafeThreadHandle threadSH = new SafeThreadHandle(); bool retVal; int errorCode = 0; // handles used in parent process SafeFileHandle standardInputWritePipeHandle = null; SafeFileHandle standardOutputReadPipeHandle = null; SafeFileHandle standardErrorReadPipeHandle = null; GCHandle environmentHandle = new GCHandle(); lock (s_createProcessLock) { try { // set up the streams if (startInfo.RedirectStandardInput || startInfo.RedirectStandardOutput || startInfo.RedirectStandardError) { if (startInfo.RedirectStandardInput) { CreatePipe(out standardInputWritePipeHandle, out startupInfo.hStdInput, true); } else { startupInfo.hStdInput = new SafeFileHandle(Interop.Kernel32.GetStdHandle(Interop.Kernel32.HandleTypes.STD_INPUT_HANDLE), false); } if (startInfo.RedirectStandardOutput) { CreatePipe(out standardOutputReadPipeHandle, out startupInfo.hStdOutput, false); } else { startupInfo.hStdOutput = new SafeFileHandle(Interop.Kernel32.GetStdHandle(Interop.Kernel32.HandleTypes.STD_OUTPUT_HANDLE), false); } if (startInfo.RedirectStandardError) { CreatePipe(out standardErrorReadPipeHandle, out startupInfo.hStdError, false); } else { startupInfo.hStdError = new SafeFileHandle(Interop.Kernel32.GetStdHandle(Interop.Kernel32.HandleTypes.STD_ERROR_HANDLE), false); } startupInfo.dwFlags = Interop.Advapi32.StartupInfoOptions.STARTF_USESTDHANDLES; } // set up the creation flags parameter int creationFlags = 0; if (startInfo.CreateNoWindow) creationFlags |= Interop.Advapi32.StartupInfoOptions.CREATE_NO_WINDOW; // set up the environment block parameter IntPtr environmentPtr = (IntPtr)0; if (startInfo._environmentVariables != null) { creationFlags |= Interop.Advapi32.StartupInfoOptions.CREATE_UNICODE_ENVIRONMENT; byte[] environmentBytes = EnvironmentVariablesToByteArray(startInfo._environmentVariables); environmentHandle = GCHandle.Alloc(environmentBytes, GCHandleType.Pinned); environmentPtr = environmentHandle.AddrOfPinnedObject(); } string workingDirectory = startInfo.WorkingDirectory; if (workingDirectory == string.Empty) workingDirectory = Directory.GetCurrentDirectory(); if (startInfo.UserName.Length != 0) { if (startInfo.Password != null && startInfo.PasswordInClearText != null) { throw new ArgumentException(SR.CantSetDuplicatePassword); } Interop.Advapi32.LogonFlags logonFlags = (Interop.Advapi32.LogonFlags)0; if (startInfo.LoadUserProfile) { logonFlags = Interop.Advapi32.LogonFlags.LOGON_WITH_PROFILE; } if (startInfo.Password != null) { IntPtr passwordPtr = Marshal.SecureStringToGlobalAllocUnicode(startInfo.Password); try { retVal = Interop.Advapi32.CreateProcessWithLogonW( startInfo.UserName, startInfo.Domain, passwordPtr, logonFlags, null, // we don't need this since all the info is in commandLine commandLine, creationFlags, environmentPtr, workingDirectory, startupInfo, // pointer to STARTUPINFO processInfo // pointer to PROCESS_INFORMATION ); if (!retVal) errorCode = Marshal.GetLastWin32Error(); } finally { Marshal.ZeroFreeGlobalAllocUnicode(passwordPtr); } } else { unsafe { fixed (char* passwordPtr = startInfo.PasswordInClearText ?? string.Empty) { retVal = Interop.Advapi32.CreateProcessWithLogonW( startInfo.UserName, startInfo.Domain, (IntPtr)passwordPtr, logonFlags, null, // we don't need this since all the info is in commandLine commandLine, creationFlags, environmentPtr, workingDirectory, startupInfo, // pointer to STARTUPINFO processInfo // pointer to PROCESS_INFORMATION ); } } if (!retVal) errorCode = Marshal.GetLastWin32Error(); } if (processInfo.hProcess != IntPtr.Zero && processInfo.hProcess != (IntPtr)INVALID_HANDLE_VALUE) procSH.InitialSetHandle(processInfo.hProcess); if (processInfo.hThread != IntPtr.Zero && processInfo.hThread != (IntPtr)INVALID_HANDLE_VALUE) threadSH.InitialSetHandle(processInfo.hThread); if (!retVal) { if (errorCode == Interop.Errors.ERROR_BAD_EXE_FORMAT || errorCode == Interop.Errors.ERROR_EXE_MACHINE_TYPE_MISMATCH) { throw new Win32Exception(errorCode, SR.InvalidApplication); } throw new Win32Exception(errorCode); } } else { retVal = Interop.Kernel32.CreateProcess( null, // we don't need this since all the info is in commandLine commandLine, // pointer to the command line string ref unused_SecAttrs, // address to process security attributes, we don't need to inherit the handle ref unused_SecAttrs, // address to thread security attributes. true, // handle inheritance flag creationFlags, // creation flags environmentPtr, // pointer to new environment block workingDirectory, // pointer to current directory name startupInfo, // pointer to STARTUPINFO processInfo // pointer to PROCESS_INFORMATION ); if (!retVal) errorCode = Marshal.GetLastWin32Error(); if (processInfo.hProcess != (IntPtr)0 && processInfo.hProcess != (IntPtr)INVALID_HANDLE_VALUE) procSH.InitialSetHandle(processInfo.hProcess); if (processInfo.hThread != (IntPtr)0 && processInfo.hThread != (IntPtr)INVALID_HANDLE_VALUE) threadSH.InitialSetHandle(processInfo.hThread); if (!retVal) { if (errorCode == Interop.Errors.ERROR_BAD_EXE_FORMAT || errorCode == Interop.Errors.ERROR_EXE_MACHINE_TYPE_MISMATCH) { throw new Win32Exception(errorCode, SR.InvalidApplication); } throw new Win32Exception(errorCode); } } } finally { // free environment block if (environmentHandle.IsAllocated) { environmentHandle.Free(); } startupInfo.Dispose(); } } if (startInfo.RedirectStandardInput) { Encoding enc = GetEncoding((int)Interop.Kernel32.GetConsoleCP()); _standardInput = new StreamWriter(new FileStream(standardInputWritePipeHandle, FileAccess.Write, 4096, false), enc, 4096); _standardInput.AutoFlush = true; } if (startInfo.RedirectStandardOutput) { Encoding enc = startInfo.StandardOutputEncoding ?? GetEncoding((int)Interop.Kernel32.GetConsoleOutputCP()); _standardOutput = new StreamReader(new FileStream(standardOutputReadPipeHandle, FileAccess.Read, 4096, false), enc, true, 4096); } if (startInfo.RedirectStandardError) { Encoding enc = startInfo.StandardErrorEncoding ?? GetEncoding((int)Interop.Kernel32.GetConsoleOutputCP()); _standardError = new StreamReader(new FileStream(standardErrorReadPipeHandle, FileAccess.Read, 4096, false), enc, true, 4096); } bool ret = false; if (!procSH.IsInvalid) { SetProcessHandle(procSH); SetProcessId((int)processInfo.dwProcessId); threadSH.Dispose(); ret = true; } return ret; }