Как получить вывод System.Diagnostics.Process?
Я запускаю ffmpeg следующим образом:
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo = new System.Diagnostics.ProcessStartInfo(ffmpegPath, myParams);
p.Start();
p.WaitForExit();
... но проблема в том, что консоль с ffmpeg появляется и исчезает сразу, поэтому я не могу получить никакой обратной связи. Я даже не знаю, правильно ли выполнялся процесс.
Итак, как я могу:
-
Сообщите, чтобы консоль оставалась открытой
-
Извлеките в С#, что консоль
отображается
Ответы
Ответ 1
Что вам нужно сделать, это захватить стандартный поток вывода:
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
// instead of p.WaitForExit(), do
string q = "";
while ( ! p.HasExited ) {
q += p.StandardOutput.ReadToEnd();
}
Вам также может понадобиться сделать что-то подобное с StandardError
. Затем вы можете сделать то, что хотите, с помощью q
.
Это немного утомительно, поскольку я обнаружил в один из моих вопросов
Как отметил Джон Скит, не так уж разумно использовать конкатенацию строк, как это; вместо этого вы должны использовать StringBuilder
:
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
// instead of p.WaitForExit(), do
StringBuilder q = new StringBuilder();
while ( ! p.HasExited ) {
q.Append(p.StandardOutput.ReadToEnd());
}
string r = q.ToString();
Ответ 2
Ответ Lucas имеет условие гонки: если процесс завершается быстро, цикл while остается (или никогда не вводится), даже если есть какой-то выход слева, то есть вы можете пропустить некоторые данные. Чтобы этого не произошло, после завершения процесса необходимо выполнить еще один ReadToEnd
.
(Обратите внимание, что по сравнению со старой версией моего ответа я больше не вижу необходимости в WaitForExit
, когда флаг process.HasExited
имеет значение true, поэтому это сводится к:)
using (var process = Process.Start(startInfo))
{
var standardOutput = new StringBuilder();
// read chunk-wise while process is running.
while (!process.HasExited)
{
standardOutput.Append(process.StandardOutput.ReadToEnd());
}
// make sure not to miss out on any remaindings.
standardOutput.Append(process.StandardOutput.ReadToEnd());
// ...
}
Ответ 3
Для более конкретного ответа, напрямую связанного с ffmpeg, передача команды "-report" в ffmpeg заставит его выгрузить журнал в текущий каталог с тем, что было сказано на дисплее процесса.
'- отчет
Удалите полную командную строку и консольный вывод в файл с именем program-YYYYMMDD-HHMMSS.log в текущем каталоге. Этот файл может быть полезно для отчетов об ошибках. Он также подразумевает подробный список.
Примечание: установка переменной среды FFREPORT для любого значения имеет тот же эффект.
Из Документация FFMpeg.
Ответ 4
Я знаю, что этот вопрос старый, но я все равно добавлю его.
Если все, что вы хотите сделать, это отобразить вывод процесса командной строки, и вы создаете процесс из окна консоли, вам нужно только перенаправить стандартный ввод (да, я знаю, что это звучит неправильно, но оно работает).
Итак:
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo = new System.Diagnostics.ProcessStartInfo(ffmpegPath, myParams);
p.UseShellExecute = false;
p.RedirectStandardInput = true;
p.Start();
p.WaitForExit();
Было бы прекрасно.