Le problème est que si vous rediriger StandardOutput
et/ou StandardError
la mémoire tampon interne peut devenir complet. Quelle que soit la commande que vous utilisez, il peut être un problème:
- Si vous attendez que le processus de sortie avant de lire
StandardOutput
le processus peut bloquer à essayer d'écrire, de sorte que le processus ne se termine jamais.
- Si vous lisez à partir d'
StandardOutput
à l'aide de ReadToEnd ensuite, votre processus peut bloquer si le processus ne se referme jamais StandardOutput
(par exemple si elle ne se termine, ou si elle est bloquée par écrit à l' StandardError
).
La solution est d'utiliser asynchrone lit pour s'assurer que le tampon de ne pas obtenir le plein. Pour éviter toute blocages et de recueillir toutes les données de sortie à partir de deux StandardOutput
et StandardError
vous pouvez faire:
using (Process process = new Process())
{
process.StartInfo.FileName = filename;
process.StartInfo.Arguments = arguments;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
StringBuilder output = new StringBuilder();
StringBuilder error = new StringBuilder();
using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false))
using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false))
{
process.OutputDataReceived += (sender, e) => {
if (e.Data == null)
{
outputWaitHandle.Set();
}
else
{
output.AppendLine(e.Data);
}
};
process.ErrorDataReceived += (sender, e) =>
{
if (e.Data == null)
{
errorWaitHandle.Set();
}
else
{
error.AppendLine(e.Data);
}
};
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
if (process.WaitForExit(timeout) &&
outputWaitHandle.WaitOne(timeout) &&
errorWaitHandle.WaitOne(timeout))
{
// Process completed. Check process.ExitCode here.
}
else
{
// Timed out.
}
}
}