public static async Task<ReactiveProcess> StartAsync(string fileName, string arguments) { var p = new ReactiveProcess {StartInfo = new ProcessStartInfo(fileName, arguments)}; try { await p.StartAsync().ConfigureAwait(false); } catch { p.Dispose(); throw; } return p; }
async Task<ProcessExitResult> LaunchAndWaitForExitAsync(ReactiveProcess process, TimeSpan? monitorOutput, TimeSpan? monitorResponding, CancellationToken token) { var task = process.StartAsync(); _launched.OnNext(Tuple.Create(process.StartInfo, process.Id)); using (SetupMonitoringDisposable(process, monitorOutput, monitorResponding)) using (token.Register(process.Kill)) await task.ConfigureAwait(false); _terminated.OnNext(Tuple.Create(process.StartInfo, process.ExitCode, process.Id)); return new ProcessExitResult(process.ExitCode, process.Id, process.StartInfo); }
static void SetupStandardOutput(LaunchAndProcessInfo info, ReactiveProcess process) { if (info.StandardOutputAction == null) return; if (!info.StartInfo.RedirectStandardOutput) throw new InvalidOperationException("Not redirected output"); process.StandardOutputObservable.Subscribe(data => info.StandardOutputAction(process, data)); }
public async Task<ProcessExitResult> LaunchAndProcessAsync(LaunchAndProcessInfo info) { using (var process = new ReactiveProcess {StartInfo = info.StartInfo.EnableRedirect()}) { SetupStandardOutput(info, process); SetupStandardError(info, process); return await LaunchAndWaitForExitAsync(process, info.MonitorOutput, info.MonitorResponding, info.CancellationToken) .ConfigureAwait(false); } }
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); } }
Timer MonitorProcessOutput(ReactiveProcess process, TimeSpan timeout) { Contract.Requires<ArgumentNullException>(process != null); Contract.Requires<ArgumentNullException>(timeout != null); var state = process.MonitorProcessOutput(); _monitorStarted.OnNext(Tuple.Create(process.StartInfo, process.Id, "Output")); return new TimerWithElapsedCancellation(MonitorInterval, () => OnOutputMonitorElapsed(process, state, timeout), (o, args) => _monitorStopped.OnNext(Tuple.Create(process.StartInfo, process.Id, "Output"))); }
CompositeDisposable SetupMonitoringDisposable(ReactiveProcess process, TimeSpan? monitorOutput, TimeSpan? monitorResponding) { var disposable = new CompositeDisposable(); if (monitorOutput.HasValue) disposable.Add(MonitorProcessOutput(process, monitorOutput.Value)); if (monitorResponding.HasValue) disposable.Add(MonitorProcessResponding(process, monitorResponding.Value)); return disposable; }