in src/common/details/helpers/process_helpers.cs [125:208]
public static async Task<ProcessOutput> RunShellCommandAsync(string command, string arguments, Dictionary<string, string>? addToEnvironment = null, Action<string>? stdOutHandler = null, Action<string>? stdErrHandler = null, Action<string>? mergedOutputHandler = null, bool captureOutput = true)
{
SHELL_DEBUG_TRACE($"COMMAND: {command} {arguments} {DictionaryToString(addToEnvironment)}");
var redirectOutput = captureOutput || stdOutHandler != null || stdErrHandler != null || mergedOutputHandler != null;
var outDoneSignal = new ManualResetEvent(false);
var errDoneSignal = new ManualResetEvent(false);
var sbOut = new StringBuilder();
var sbErr = new StringBuilder();
var sbMerged = new StringBuilder();
var stdOutReceived = (string? data) => {
if (data != null)
{
sbOut.AppendLine(data);
sbMerged.AppendLine(data);
if (stdOutHandler != null) stdOutHandler(data);
if (mergedOutputHandler != null) mergedOutputHandler(data);
}
else
{
outDoneSignal.Set();
}
};
var stdErrReceived = (string? data) => {
if (data != null)
{
sbErr.AppendLine(data);
sbMerged.AppendLine(data);
if (stdErrHandler != null) stdErrHandler(data);
if (mergedOutputHandler != null) mergedOutputHandler(data);
}
else
{
errDoneSignal.Set();
}
};
Process? process;
try
{
process = StartShellCommandProcess(command, arguments, addToEnvironment, redirectOutput);
}
catch (Exception processException)
{
SHELL_DEBUG_TRACE($"ERROR: {processException}");
return new ProcessOutput()
{
ExitCode = -1,
StdError = processException.ToString()
};
}
if (process != null)
{
if (redirectOutput)
{
process.OutputDataReceived += (sender, e) => stdOutReceived(e.Data);
process.ErrorDataReceived += (sender, e) => stdErrReceived(e.Data);
process.BeginOutputReadLine();
process.BeginErrorReadLine();
}
await process.WaitForExitAsync();
if (redirectOutput)
{
outDoneSignal.WaitOne();
errDoneSignal.WaitOne();
}
}
var output = new ProcessOutput();
output.StdOutput = sbOut.ToString().Trim(' ', '\r', '\n');
output.StdError = sbErr.ToString().Trim(' ', '\r', '\n');
output.MergedOutput = sbMerged.ToString().Trim(' ', '\r', '\n');
output.ExitCode = process?.ExitCode ?? -1;
if (!string.IsNullOrEmpty(output.StdOutput)) SHELL_DEBUG_TRACE($"---\nSTDOUT\n---\n{output.StdOutput}");
if (!string.IsNullOrEmpty(output.StdError)) SHELL_DEBUG_TRACE($"---\nSTDERR\n---\n{output.StdError}");
return output;
}