async Task<ProcessExitResult> LaunchAndWaitForExitAsync(ReactiveProcess process, TimeSpan? monitorOutput, TimeSpan? monitorResponding) { var task = process.StartAsync(); _launched.OnNext(Tuple.Create(process.StartInfo, process.Id)); using (SetupMonitoringDisposable(process, monitorOutput, monitorResponding)) await task.ConfigureAwait(false); _terminated.OnNext(Tuple.Create(process.StartInfo, process.ExitCode, process.Id)); return new ProcessExitResult(process.ExitCode, process.Id, process.StartInfo); }
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.TryKill)) await task.ConfigureAwait(false); _terminated.OnNext(Tuple.Create(process.StartInfo, process.ExitCode, process.Id)); token.ThrowIfCancellationRequested(); return new ProcessExitResult(process.ExitCode, process.Id, process.StartInfo); }
static IDisposable SetupStandardOutput(LaunchAndProcessInfo info, ReactiveProcess process) { if (!info.StartInfo.RedirectStandardOutput) throw new InvalidOperationException("Not redirected output"); var dsp = new CompositeDisposable(); if (info.StandardOutputObs != null) dsp.Add(info.StandardOutputObs(process.StandardOutputObservable)); if (info.StandardOutputAction != null) dsp.Add(process.StandardOutputObservable.Subscribe(data => info.StandardOutputAction(process, data))); return dsp; }
public async Task<ProcessExitResult> LaunchAndProcessAsync(LaunchAndProcessInfo info) { using (var process = new ReactiveProcess {StartInfo = info.StartInfo.EnableRedirect()}) { using (SetupStandardOutput(info, process)) using (SetupStandardError(info, process)) return await LaunchAndWaitForExitAsync(process, info.MonitorOutput, info.MonitorResponding, info.CancellationToken) .ConfigureAwait(false); } }
public async Task<ProcessExitResult> LaunchElevatedAsync(BasicLaunchInfo info) { info.StartInfo.EnableRunAsAdministrator(); ProcessBLI(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), () => _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; }