in src/dotnet/ReSharperPlugin.DotNetDisassembler/JitDisasm/ProcessUtils.cs [12:100]
public static async ValueTask<ProcessResult> RunProcessAsync(
string path,
string args = "",
Dictionary<string, string> envVars = null,
string workingDir = null,
Action<bool, string> outputLogger = null,
TimeSpan timeout = default,
CancellationToken cancellationToken = default)
{
var logger = new StringBuilder();
var loggerForErrors = new StringBuilder();
var loggerLock = new object();
Process process = null;
using var timeoutCts = CreateTimeoutCts(timeout, cancellationToken);
var effectiveToken = timeoutCts?.Token ?? cancellationToken;
try
{
var processStartInfo = new ProcessStartInfo
{
FileName = path,
UseShellExecute = false,
CreateNoWindow = true,
RedirectStandardError = true,
RedirectStandardOutput = true,
Arguments = args,
};
if (workingDir != null)
processStartInfo.WorkingDirectory = workingDir;
if (envVars != null)
{
foreach (var envVar in envVars)
processStartInfo.EnvironmentVariables[envVar.Key] = envVar.Value;
}
effectiveToken.ThrowIfCancellationRequested();
process = Process.Start(processStartInfo);
effectiveToken.ThrowIfCancellationRequested();
process!.ErrorDataReceived += (sender, e) =>
{
outputLogger?.Invoke(true, e.Data + "\n");
lock (loggerLock)
{
logger.AppendLine(e.Data);
loggerForErrors.AppendLine(e.Data);
}
};
process.OutputDataReceived += (sender, e) =>
{
outputLogger?.Invoke(false, e.Data + "\n");
lock (loggerLock)
{
logger.AppendLine(e.Data);
}
};
process.BeginOutputReadLine();
process.BeginErrorReadLine();
await process.WaitForExitAsync(effectiveToken);
return new ProcessResult { Error = loggerForErrors.ToString().Trim('\r', '\n'), Output = logger.ToString().Trim('\r', '\n') };
}
catch (OperationCanceledException)
{
return new ProcessResult
{
Output = logger.ToString().Trim('\r', '\n'),
Error = loggerForErrors.ToString().Trim('\r', '\n'),
IsTimeout = effectiveToken.IsCancellationRequested && !cancellationToken.IsCancellationRequested,
IsCancelled = true
};
}
catch (Exception e)
{
return new ProcessResult
{
Error = $"RunProcess failed:{e.Message}.\npath={path}\nargs={args}\nworkingdir={workingDir ?? Environment.CurrentDirectory}\n{loggerForErrors}",
Exception = e
};
}
finally
{
process.KillProccessSafe();
}
}