in Configurator/Base/Classes/Utilities.cs [1334:1439]
public static ProcessResult RunProcess(string executableFilePath, string arguments, string workingDirectory, Action<string> outputRedirectionDelegate, Action<string> errorRedirectionDelegate, bool waitForExit, bool hideProcessMessages = false, bool waitLongerWorkaround = false)
{
if (string.IsNullOrEmpty(executableFilePath)
|| !File.Exists(executableFilePath))
{
return null;
}
ProcessResult result = null;
try
{
if (string.IsNullOrEmpty(workingDirectory)
|| !Directory.Exists(workingDirectory))
{
workingDirectory = Path.GetDirectoryName(executableFilePath);
}
var processStartInfo = new ProcessStartInfo(executableFilePath)
{
Arguments = arguments.Trim(),
RedirectStandardInput = true,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
// It might seems this validation is not needed, but Path.GetDirectoryName name above could still return null or empty string.
if (!string.IsNullOrEmpty(workingDirectory))
{
processStartInfo.WorkingDirectory = workingDirectory;
}
if (!hideProcessMessages)
{
outputRedirectionDelegate?.Invoke(string.Format(Resources.StartingProcessDetailsText, processStartInfo.FileName, processStartInfo.Arguments));
}
var process = Process.Start(processStartInfo);
if (process == null)
{
return null;
}
int pid = process.Id;
var outputBuilder = new StringBuilder();
var errorBuilder = new StringBuilder();
var processName = process.ProcessName;
process.OutputDataReceived += (sender, e) =>
{
outputRedirectionDelegate?.Invoke(e.Data);
outputBuilder.AppendLine(e.Data);
};
process.ErrorDataReceived += (sender, e) =>
{
errorRedirectionDelegate?.Invoke(e.Data);
errorBuilder.AppendLine(e.Data);
};
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.StandardInput.Close();
if (waitForExit)
{
if (waitLongerWorkaround)
{
while (!process.WaitForExit(3000))
{
if (GetRunningProcess(pid) != null)
{
// This is a dummy block, its intention is purely to act as a workaround for processes
// that do not end gracefully when waiting for them indefinitely (like the MySQL Shell one).
}
}
}
else
{
// Wait indefinitely
process.WaitForExit();
}
}
result = new ProcessResult(
process.HasExited ? null : process,
process.HasExited ? (int?)process.ExitCode : null,
outputBuilder.ToString(),
errorBuilder.ToString());
if (!hideProcessMessages)
{
outputRedirectionDelegate?.Invoke(!process.HasExited
? string.Format(Resources.StartedAndRunningProcessSuccessfullyText, processName, pid)
: string.Format(Resources.StartedAndExitedProcessSuccessfullyText, processName, pid, process.ExitCode));
}
if (process.HasExited)
{
process.Dispose();
}
}
catch (Exception ex)
{
Logger.LogException(ex);
errorRedirectionDelegate?.Invoke(string.Format(Resources.StartedProcessErrorText, Path.GetFileNameWithoutExtension(executableFilePath), ex.Message));
}
return result;
}