private static Task<ProcessOutput> CreateTask( Process process, TaskCompletionSource<ProcessOutput> taskCompletionSource, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (taskCompletionSource == null) { throw new ArgumentException("taskCompletionSource"); } if (process == null) { return taskCompletionSource.Task; } var errorLines = new List<string>(); var outputLines = new List<string>(); process.OutputDataReceived += (s, e) => { if (e.Data != null) { outputLines.Add(e.Data); } }; process.ErrorDataReceived += (s, e) => { if (e.Data != null) { errorLines.Add(e.Data); } }; process.Exited += (s, e) => { var processOutput = new ProcessOutput(process.ExitCode, outputLines, errorLines); taskCompletionSource.TrySetResult(processOutput); }; var registration = cancellationToken.Register(() => { if (taskCompletionSource.TrySetCanceled()) { // If the underlying process is still running, we should kill it if (!process.HasExited) { try { process.Kill(); } catch (InvalidOperationException) { // Ignore, since the process is already dead } } } }); return taskCompletionSource.Task; }
private static Task <ProcessOutput> CreateTask( Process process, TaskCompletionSource <ProcessOutput> taskCompletionSource, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (taskCompletionSource == null) { throw new ArgumentException("taskCompletionSource"); } if (process == null) { return(taskCompletionSource.Task); } var errorLines = new List <string>(); var outputLines = new List <string>(); process.OutputDataReceived += (s, e) => { if (e.Data != null) { outputLines.Add(e.Data); } }; process.ErrorDataReceived += (s, e) => { if (e.Data != null) { errorLines.Add(e.Data); } }; process.Exited += (s, e) => { // We must call WaitForExit to make sure we've received all OutputDataReceived/ErrorDataReceived calls // or else we'll be returning a list we're still modifying. For paranoia, we'll start a task here rather // than enter right back into the Process type and start a wait which isn't guaranteed to be safe. Task.Run(() => { process.WaitForExit(); var processOutput = new ProcessOutput(process.ExitCode, outputLines, errorLines); taskCompletionSource.TrySetResult(processOutput); }); }; var registration = cancellationToken.Register(() => { if (taskCompletionSource.TrySetCanceled()) { // If the underlying process is still running, we should kill it if (!process.HasExited) { try { process.Kill(); } catch (InvalidOperationException) { // Ignore, since the process is already dead } } } }); return(taskCompletionSource.Task); }
private static Task<ProcessOutput> CreateTask( Process process, TaskCompletionSource<ProcessOutput> taskCompletionSource, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (taskCompletionSource == null) { throw new ArgumentException("taskCompletionSource"); } if (process == null) { return taskCompletionSource.Task; } var errorLines = new List<string>(); var outputLines = new List<string>(); process.OutputDataReceived += (s, e) => { if (e.Data != null) { outputLines.Add(e.Data); } }; process.ErrorDataReceived += (s, e) => { if (e.Data != null) { errorLines.Add(e.Data); } }; process.Exited += (s, e) => { // We must call WaitForExit to make sure we've received all OutputDataReceived/ErrorDataReceived calls // or else we'll be returning a list we're still modifying. For paranoia, we'll start a task here rather // than enter right back into the Process type and start a wait which isn't guaranteed to be safe. Task.Run(() => { process.WaitForExit(); var processOutput = new ProcessOutput(process.ExitCode, outputLines, errorLines); taskCompletionSource.TrySetResult(processOutput); }); }; var registration = cancellationToken.Register(() => { if (taskCompletionSource.TrySetCanceled()) { // If the underlying process is still running, we should kill it if (!process.HasExited) { try { process.Kill(); } catch (InvalidOperationException) { // Ignore, since the process is already dead } } } }); return taskCompletionSource.Task; }
private static Task <ProcessOutput> CreateTask( Process process, TaskCompletionSource <ProcessOutput> taskCompletionSource, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); if (taskCompletionSource == null) { throw new ArgumentException("taskCompletionSource"); } if (process == null) { return(taskCompletionSource.Task); } var errorLines = new List <string>(); var outputLines = new List <string>(); process.OutputDataReceived += (s, e) => { if (e.Data != null) { outputLines.Add(e.Data); } }; process.ErrorDataReceived += (s, e) => { if (e.Data != null) { errorLines.Add(e.Data); } }; process.Exited += (s, e) => { var processOutput = new ProcessOutput(process.ExitCode, outputLines, errorLines); taskCompletionSource.TrySetResult(processOutput); }; var registration = cancellationToken.Register(() => { if (taskCompletionSource.TrySetCanceled()) { // If the underlying process is still running, we should kill it if (!process.HasExited) { try { process.Kill(); } catch (InvalidOperationException) { // Ignore, since the process is already dead } } } }); return(taskCompletionSource.Task); }
private static Task <ProcessOutput> CreateProcessTask( ProcessStartInfo processStartInfo, bool lowPriority, TaskCompletionSource <ProcessOutput> taskCompletionSource, CancellationToken cancellationToken) { var errorLines = new List <string>(); var outputLines = new List <string>(); var process = new Process(); process.EnableRaisingEvents = true; process.StartInfo = processStartInfo; process.OutputDataReceived += (s, e) => { if (e.Data != null) { outputLines.Add(e.Data); } }; process.ErrorDataReceived += (s, e) => { if (e.Data != null) { errorLines.Add(e.Data); } }; process.Exited += (s, e) => { // We must call WaitForExit to make sure we've received all OutputDataReceived/ErrorDataReceived calls // or else we'll be returning a list we're still modifying. For paranoia, we'll start a task here rather // than enter right back into the Process type and start a wait which isn't guaranteed to be safe. Task.Run(() => { process.WaitForExit(); var processOutput = new ProcessOutput(process.ExitCode, outputLines, errorLines); taskCompletionSource.TrySetResult(processOutput); }); }; var registration = cancellationToken.Register(() => { if (taskCompletionSource.TrySetCanceled()) { // If the underlying process is still running, we should kill it if (!process.HasExited) { try { process.Kill(); } catch (InvalidOperationException) { // Ignore, since the process is already dead } } } }); process.Start(); if (lowPriority) { process.PriorityClass = ProcessPriorityClass.BelowNormal; } if (processStartInfo.RedirectStandardOutput) { process.BeginOutputReadLine(); } if (processStartInfo.RedirectStandardError) { process.BeginErrorReadLine(); } return(taskCompletionSource.Task); }