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.FreeBSTR (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.StartExitCallbackIfNeeded (); return(ret); }
private static bool Start_noshell (ProcessStartInfo startInfo, Process process) { ProcInfo proc_info=new ProcInfo(); IntPtr stdin_rd = IntPtr.Zero, stdin_wr = IntPtr.Zero; IntPtr stdout_wr; IntPtr stderr_wr; bool ret; MonoIOError error; 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; } if (startInfo.RedirectStandardInput == true) { if (IsWindows) { int DUPLICATE_SAME_ACCESS = 0x00000002; IntPtr stdin_wr_tmp; ret = MonoIO.CreatePipe (out stdin_rd, out stdin_wr_tmp); if (ret) { ret = MonoIO.DuplicateHandle (Process.GetCurrentProcess ().Handle, stdin_wr_tmp, Process.GetCurrentProcess ().Handle, out stdin_wr, 0, 0, DUPLICATE_SAME_ACCESS); MonoIO.Close (stdin_wr_tmp, out error); } } else { ret = MonoIO.CreatePipe (out stdin_rd, out stdin_wr); } if (ret == false) { throw new IOException ("Error creating standard input pipe"); } } else { stdin_rd = MonoIO.ConsoleInput; /* This is required to stop the * &$*£ing stupid compiler moaning * that stdin_wr is unassigned, below. */ stdin_wr = (IntPtr)0; } if (startInfo.RedirectStandardOutput == true) { IntPtr out_rd = IntPtr.Zero; if (IsWindows) { IntPtr out_rd_tmp; int DUPLICATE_SAME_ACCESS = 0x00000002; ret = MonoIO.CreatePipe (out out_rd_tmp, out stdout_wr); if (ret) { MonoIO.DuplicateHandle (Process.GetCurrentProcess ().Handle, out_rd_tmp, Process.GetCurrentProcess ().Handle, out out_rd, 0, 0, DUPLICATE_SAME_ACCESS); MonoIO.Close (out_rd_tmp, out error); } } else { ret = MonoIO.CreatePipe (out out_rd, out stdout_wr); } process.stdout_rd = out_rd; if (ret == false) { if (startInfo.RedirectStandardInput == true) { MonoIO.Close (stdin_rd, out error); MonoIO.Close (stdin_wr, out error); } throw new IOException ("Error creating standard output pipe"); } } else { process.stdout_rd = (IntPtr)0; stdout_wr = MonoIO.ConsoleOutput; } if (startInfo.RedirectStandardError == true) { IntPtr err_rd = IntPtr.Zero; if (IsWindows) { IntPtr err_rd_tmp; int DUPLICATE_SAME_ACCESS = 0x00000002; ret = MonoIO.CreatePipe (out err_rd_tmp, out stderr_wr); if (ret) { MonoIO.DuplicateHandle (Process.GetCurrentProcess ().Handle, err_rd_tmp, Process.GetCurrentProcess ().Handle, out err_rd, 0, 0, DUPLICATE_SAME_ACCESS); MonoIO.Close (err_rd_tmp, out error); } } else { ret = MonoIO.CreatePipe (out err_rd, out stderr_wr); } process.stderr_rd = err_rd; if (ret == false) { if (startInfo.RedirectStandardInput == true) { MonoIO.Close (stdin_rd, out error); MonoIO.Close (stdin_wr, out error); } if (startInfo.RedirectStandardOutput == true) { MonoIO.Close (process.stdout_rd, out error); MonoIO.Close (stdout_wr, out error); } throw new IOException ("Error creating standard error pipe"); } } else { process.stderr_rd = (IntPtr)0; stderr_wr = MonoIO.ConsoleError; } FillUserInfo (startInfo, ref proc_info); try { ret = CreateProcess_internal (startInfo, stdin_rd, stdout_wr, stderr_wr, ref proc_info); } finally { if (proc_info.Password != IntPtr.Zero) Marshal.FreeBSTR (proc_info.Password); proc_info.Password = IntPtr.Zero; } if (!ret) { if (startInfo.RedirectStandardInput == true) { MonoIO.Close (stdin_rd, out error); MonoIO.Close (stdin_wr, out error); } if (startInfo.RedirectStandardOutput == true) { MonoIO.Close (process.stdout_rd, out error); MonoIO.Close (stdout_wr, out error); } if (startInfo.RedirectStandardError == true) { MonoIO.Close (process.stderr_rd, out error); MonoIO.Close (stderr_wr, out error); } throw new Win32Exception (-proc_info.pid, "ApplicationName='" + startInfo.FileName + "', CommandLine='" + startInfo.Arguments + "', CurrentDirectory='" + startInfo.WorkingDirectory + "', Native error= " + Win32Exception.W32ErrorMessage (-proc_info.pid)); } process.process_handle = proc_info.process_handle; process.pid = proc_info.pid; if (startInfo.RedirectStandardInput == true) { MonoIO.Close (stdin_rd, out error); process.input_stream = new StreamWriter (new MonoSyncFileStream (stdin_wr, FileAccess.Write, true, 8192), Console.Out.Encoding); process.input_stream.AutoFlush = true; } #if NET_2_0 Encoding stdoutEncoding = startInfo.StandardOutputEncoding ?? Console.Out.Encoding; Encoding stderrEncoding = startInfo.StandardErrorEncoding ?? Console.Out.Encoding; #else Encoding stdoutEncoding = Console.Out.Encoding; Encoding stderrEncoding = stdoutEncoding; #endif if (startInfo.RedirectStandardOutput == true) { MonoIO.Close (stdout_wr, out error); process.output_stream = new StreamReader (new MonoSyncFileStream (process.stdout_rd, FileAccess.Read, true, 8192), stdoutEncoding, true, 8192); } if (startInfo.RedirectStandardError == true) { MonoIO.Close (stderr_wr, out error); process.error_stream = new StreamReader (new MonoSyncFileStream (process.stderr_rd, FileAccess.Read, true, 8192), stderrEncoding, true, 8192); } process.StartExitCallbackIfNeeded (); 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); process.stdout_rd = stdout_read; } else { process.stdout_rd = IntPtr.Zero; stdout_write = MonoIO.ConsoleOutput; } if (startInfo.RedirectStandardError) { CreatePipe (out stderr_read, out stderr_write, false); process.stderr_rd = stderr_read; } else { process.stderr_rd = 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); process.input_stream = new StreamWriter (new FileStream (new SafeFileHandle (stdin_write, false), FileAccess.Write, 8192, false), Console.InputEncoding) { 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 (new SafeFileHandle (stdout_read, false), FileAccess.Read, 8192, false), stdoutEncoding, true, 8192); } if (startInfo.RedirectStandardError) { MonoIO.Close (stderr_write, out error); Encoding stderrEncoding = startInfo.StandardErrorEncoding ?? Console.Out.Encoding; process.error_stream = new StreamReader (new FileStream (new SafeFileHandle (stderr_read, false), FileAccess.Read, 8192, false), stderrEncoding, true, 8192); } process.StartExitCallbackIfNeeded (); return true; }