82 public async Task<ProcessExecutionResult>
RunAsync(
85 string? workingDirectory,
88 CancellationToken cancellationToken)
90 if (
string.IsNullOrWhiteSpace(fileName))
96 Message =
"Executable path is empty."
100 if (!File.Exists(fileName))
106 Message = $
"Executable not found: {fileName}"
111 if (!Directory.Exists(resolvedWorkingDirectory))
117 Message = $
"Working directory not found: {resolvedWorkingDirectory}"
121 StringBuilder output =
new();
122 StringBuilder error =
new();
123 int outputLimit = maxOutputChars <= 0 ? 6000 : maxOutputChars;
125 ProcessStartInfo startInfo =
new()
128 Arguments = arguments,
129 WorkingDirectory = resolvedWorkingDirectory,
130 UseShellExecute =
false,
131 RedirectStandardOutput =
true,
132 RedirectStandardError =
true,
133 CreateNoWindow =
true
136 using Process process =
new() { StartInfo = startInfo, EnableRaisingEvents =
true };
140 process.OutputDataReceived += (_, e) =>
AppendLine(output, e.Data, outputLimit);
141 process.ErrorDataReceived += (_, e) =>
AppendLine(error, e.Data, outputLimit);
143 if (!process.Start())
149 Message = $
"Failed to start process: {fileName}"
153 process.BeginOutputReadLine();
154 process.BeginErrorReadLine();
156 using CancellationTokenSource timeoutSource =
new(timeout);
157 using CancellationTokenSource linkedSource = CancellationTokenSource.CreateLinkedTokenSource(
159 timeoutSource.Token);
163 await process.WaitForExitAsync(linkedSource.Token).ConfigureAwait(
false);
165 catch (OperationCanceledException)
173 Output = output.ToString(),
174 Error = error.ToString(),
175 Message = timeoutSource.IsCancellationRequested
176 ? $
"Process timed out: {fileName} {arguments}"
177 : $
"Process canceled: {fileName} {arguments}"
183 IsSuccess = process.ExitCode == 0,
184 ExitCode = process.ExitCode,
185 Output = output.ToString(),
186 Error = error.ToString(),
187 Message = process.ExitCode == 0
188 ?
"Process completed successfully."
189 : $
"Process failed with exit code {process.ExitCode}."
198 Output = output.ToString(),
199 Error = error.ToString(),