public ProcessExitResultWithOutput LaunchAndGrab(BasicLaunchInfo info) {
     var outputBuilder = new StringBuilder();
     var errorBuilder = new StringBuilder();
     var outInfo = LaunchAndProcess(new LaunchAndProcessInfo(info.StartInfo.EnableRedirect()) {
         StandardOutputAction = (process, data) => outputBuilder.AppendLine(data),
         StandardErrorAction = (process, data) => errorBuilder.AppendLine(data),
         MonitorOutput = info.MonitorOutput,
         MonitorResponding = info.MonitorResponding
     });
     return new ProcessExitResultWithOutput(outInfo.ExitCode, outInfo.Id, info.StartInfo,
         outputBuilder.ToString(),
         errorBuilder.ToString());
 }
 public ProcessExitResult Launch(BasicLaunchInfo info) {
     using (var process = new Process {StartInfo = info.StartInfo}) {
         LaunchAndWaitForExit(process, info.MonitorOutput, info.MonitorResponding);
         return new ProcessExitResult(process.ExitCode, process.Id, info.StartInfo);
     }
 }
 public abstract Process Launch(BasicLaunchInfo info);
 public async Task<ProcessExitResult> LaunchAsync(BasicLaunchInfo info) {
     using (var process = new ReactiveProcess {StartInfo = info.StartInfo}) {
         return
             await
                 LaunchAndWaitForExitAsync(process, info.MonitorOutput, info.MonitorResponding,
                     info.CancellationToken)
                     .ConfigureAwait(false);
     }
 }
 public Task<ProcessExitResultWithOutput> LaunchAndGrabAsync(BasicLaunchInfo info) {
     Contract.Requires<ArgumentNullException>(info != null);
     return default(Task<ProcessExitResultWithOutput>);
 }