Example #1
0
		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);
		}
Example #2
0
		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;
		}