public ITeedProcess Invoke() { if (!CanInvoke) { throw new InvalidOperationException(CannotInvokeMessage); } CanInvoke = false; ITeedProcess stdin = null; if (RedirectedStandardInput != null) { stdin = RedirectedStandardInput.Invoke(); } try { return(new PipedProcess(FilePath, BaseDirectory, WorkingDirectory, Arguments, stdin, RedirectedStandardError, standardErrorAppend)); } catch { if (stdin != null) { stdin.Terminate(); } throw; } }
public void Terminate() { lock (this) { if (processHandle != IntPtr.Zero) { Win32.TerminateProcess(processHandle, 777); if (RedirectedStandardInput != null) { RedirectedStandardInput.Terminate(); } } } }
public override string ToString() { StringBuilder sb = new StringBuilder(); if (RedirectedStandardInput != null) { sb.AppendLine(RedirectedStandardInput.ToString()) .AppendLine("WILL BE REDIRECTED TO"); } sb.AppendLine("{") .Append(" FilePath = ") .Append(FilePath == null ? "(null)" : FilePath) .AppendLine(",") .Append(" BaseDirectory = ") .Append(BaseDirectory == null ? "(null)" : BaseDirectory) .AppendLine(",") .Append(" WorkingDirectory = ") .Append(WorkingDirectory == null ? "(null)" : WorkingDirectory) .AppendLine(",") .Append(" RedirectedStandardError = ") .Append(RedirectedStandardError == null ? "(null)" : RedirectedStandardError) .AppendLine(",") .Append(" StandardErrorAppend = ") .Append(StandardErrorAppend == null ? "(null)" : StandardErrorAppend.ToString()) .AppendLine(",") .Append(" CanInvoke = ") .AppendLine(CanInvoke.ToString()) .AppendLine("}") .Append("Arguments:"); if (arguments.Count == 0) { sb.AppendLine().Append(" (empty)"); } else { foreach (string s in arguments) { sb.AppendLine().Append(" ").Append(s); } } return(sb.ToString()); }
void StartProcess() { IntPtr stdin = IntPtr.Zero; IntPtr stdoutRead = IntPtr.Zero; IntPtr stdoutWrite = IntPtr.Zero; IntPtr stderr = IntPtr.Zero; try { Win32.StartupInfo startupInfo = new Win32.StartupInfo(); startupInfo.Initialize(); startupInfo.Flags = Win32.StartProcessFlags.UseStdHandles; #region Set stdin { if (RedirectedStandardInput != null) { stdin = RedirectedStandardInput.ReleaseStandardOutputReadHandle(); Helper.EnsureHandleInheritable(stdin); } else { /* Duplicate the handle so that * the cleaning logic is unified. */ stdin = Helper.DuplicateHandleForInheritance( Win32.GetStdHandle(Win32.StandardHandleId.StandardInput)); } startupInfo.StandardInput = stdin; } #endregion Set stdin #region Set stdout { Win32.SecurityAttributes pipeAttributes = new Win32.SecurityAttributes(); pipeAttributes.Initialize(); if (Win32.CreatePipe(out stdoutRead, out stdoutWrite, ref pipeAttributes, 4096) == Win32.Bool.False) { stdoutRead = IntPtr.Zero; stdoutWrite = IntPtr.Zero; int lastError = Marshal.GetLastWin32Error(); throw new Win32Exception(lastError, string.Format(CouldNotCreatePipeErrorFormat, lastError)); } Helper.EnsureHandleInheritable(stdoutWrite); startupInfo.StandardOutput = stdoutWrite; } #endregion Set stdout #region Set stderr { if (RedirectedStandardError != null) { stderr = standardErrorAppend ? Helper.OpenAppendFile(RedirectedStandardError) : Helper.OpenTruncatedFile(RedirectedStandardError); Helper.EnsureHandleInheritable(stderr); } else { stderr = Helper.DuplicateHandleForInheritance( Win32.GetStdHandle(Win32.StandardHandleId.StandardError)); } startupInfo.StandardError = stderr; } #endregion Set stderr Win32.ProcessInformation processInformation; /* Create the process suspended, * and resume it only after we * have started waiting for it. */ if (Win32.CreateProcess(null, BuildCommandLine(), IntPtr.Zero, IntPtr.Zero, Win32.Bool.True, Win32.ProcessCreationFlags.CreateSuspended, IntPtr.Zero, InitialWorkingDirectory, ref startupInfo, out processInformation) == Win32.Bool.False) { int lastError = Marshal.GetLastWin32Error(); throw new Win32Exception(lastError, string.Format(CouldNotCreateProcessErrorFormat, lastError)); } hasExited = false; processHandle = processInformation.HandleToProcess; ProcessId = processInformation.ProcessId; new Thread(WaitForProcessExitWorker).Start(this); Win32.ResumeThread(processInformation.HandleToThread); Win32.CloseHandle(processInformation.HandleToThread); stdoutReadHandle = stdoutRead; /* Prevent this very handle from being * closed. Other handles are useless now * and will be closed in "finally". */ stdoutRead = IntPtr.Zero; } finally { if (stdin != IntPtr.Zero) { Win32.CloseHandle(stdin); } if (stdoutRead != IntPtr.Zero) { Win32.CloseHandle(stdoutRead); } if (stdoutWrite != IntPtr.Zero) { Win32.CloseHandle(stdoutWrite); } if (stderr != IntPtr.Zero) { Win32.CloseHandle(stderr); } } }