private static bool Start_shell (ProcessStartInfo startInfo, Process process) { ProcInfo proc_info=new ProcInfo(); bool ret; if (startInfo.RedirectStandardInput || startInfo.RedirectStandardOutput || startInfo.RedirectStandardError) { throw new InvalidOperationException ("UseShellExecute must be false when redirecting I/O."); } if (startInfo.HaveEnvVars) throw new InvalidOperationException ("UseShellExecute must be false in order to use environment variables."); FillUserInfo (startInfo, ref proc_info); try { ret = ShellExecuteEx_internal (startInfo, ref proc_info); } finally { if (proc_info.Password != IntPtr.Zero) Marshal.ZeroFreeBSTR (proc_info.Password); proc_info.Password = IntPtr.Zero; } if (!ret) { throw new Win32Exception (-proc_info.pid); } process.process_handle = proc_info.process_handle; process.pid = proc_info.pid; process.StartBackgroundWaitForExit (); return(ret); }
static bool Start_noshell (ProcessStartInfo startInfo, Process process) { var proc_info = new ProcInfo (); if (startInfo.HaveEnvVars) { string [] strs = new string [startInfo.EnvironmentVariables.Count]; startInfo.EnvironmentVariables.Keys.CopyTo (strs, 0); proc_info.envKeys = strs; strs = new string [startInfo.EnvironmentVariables.Count]; startInfo.EnvironmentVariables.Values.CopyTo (strs, 0); proc_info.envValues = strs; } MonoIOError error; IntPtr stdin_read = IntPtr.Zero, stdin_write = IntPtr.Zero; IntPtr stdout_read = IntPtr.Zero, stdout_write = IntPtr.Zero; IntPtr stderr_read = IntPtr.Zero, stderr_write = IntPtr.Zero; try { if (startInfo.RedirectStandardInput) { CreatePipe (out stdin_read, out stdin_write, true); } else { stdin_read = MonoIO.ConsoleInput; stdin_write = IntPtr.Zero; } if (startInfo.RedirectStandardOutput) { CreatePipe (out stdout_read, out stdout_write, false); } else { stdout_read = IntPtr.Zero; stdout_write = MonoIO.ConsoleOutput; } if (startInfo.RedirectStandardError) { CreatePipe (out stderr_read, out stderr_write, false); } else { stderr_read = IntPtr.Zero; stderr_write = MonoIO.ConsoleError; } FillUserInfo (startInfo, ref proc_info); // // FIXME: For redirected pipes we need to send descriptors of // stdin_write, stdout_read, stderr_read to child process and // close them there (fork makes exact copy of parent's descriptors) // if (!CreateProcess_internal (startInfo, stdin_read, stdout_write, stderr_write, ref proc_info)) { throw new Win32Exception (-proc_info.pid, "ApplicationName='" + startInfo.FileName + "', CommandLine='" + startInfo.Arguments + "', CurrentDirectory='" + startInfo.WorkingDirectory + "', Native error= " + Win32Exception.W32ErrorMessage (-proc_info.pid)); } } catch { if (startInfo.RedirectStandardInput) { if (stdin_read != IntPtr.Zero) MonoIO.Close (stdin_read, out error); if (stdin_write != IntPtr.Zero) MonoIO.Close (stdin_write, out error); } if (startInfo.RedirectStandardOutput) { if (stdout_read != IntPtr.Zero) MonoIO.Close (stdout_read, out error); if (stdout_write != IntPtr.Zero) MonoIO.Close (stdout_write, out error); } if (startInfo.RedirectStandardError) { if (stderr_read != IntPtr.Zero) MonoIO.Close (stderr_read, out error); if (stderr_write != IntPtr.Zero) MonoIO.Close (stderr_write, out error); } throw; } finally { if (proc_info.Password != IntPtr.Zero) { Marshal.ZeroFreeBSTR (proc_info.Password); proc_info.Password = IntPtr.Zero; } } process.process_handle = proc_info.process_handle; process.pid = proc_info.pid; if (startInfo.RedirectStandardInput) { // // FIXME: The descriptor needs to be closed but due to wapi io-layer // not coping with duplicated descriptors any StandardInput write fails // // MonoIO.Close (stdin_read, out error); #if MOBILE var stdinEncoding = Encoding.Default; #else var stdinEncoding = Console.InputEncoding; #endif process.input_stream = new StreamWriter (new FileStream (stdin_write, FileAccess.Write, true, 8192), stdinEncoding) { AutoFlush = true }; } if (startInfo.RedirectStandardOutput) { MonoIO.Close (stdout_write, out error); Encoding stdoutEncoding = startInfo.StandardOutputEncoding ?? Console.Out.Encoding; process.output_stream = new StreamReader (new FileStream (stdout_read, FileAccess.Read, true, 8192), stdoutEncoding, true); } if (startInfo.RedirectStandardError) { MonoIO.Close (stderr_write, out error); Encoding stderrEncoding = startInfo.StandardErrorEncoding ?? Console.Out.Encoding; process.error_stream = new StreamReader (new FileStream (stderr_read, FileAccess.Read, true, 8192), stderrEncoding, true); } process.StartBackgroundWaitForExit (); return true; }