Как вызвать консольное приложение из моего приложения .NET и захватить все выходные данные, созданные в консоли?
(Помните, что я не хочу сначала сохранять информацию в файле, а затем relist, так как мне бы хотелось получить ее как live.)
Как вызвать консольное приложение из моего приложения .NET и захватить все выходные данные, созданные в консоли?
(Помните, что я не хочу сначала сохранять информацию в файле, а затем relist, так как мне бы хотелось получить ее как live.)
Этого можно легко достичь, используя свойство ProcessStartInfo.RedirectStandardOutput. Полный образец содержится в связанной документации MSDN; единственное предостережение в том, что вам, возможно, придется перенаправить стандартный поток ошибок, а также увидеть все выходные данные вашего приложения.
Process compiler = new Process();
compiler.StartInfo.FileName = "csc.exe";
compiler.StartInfo.Arguments = "/r:System.dll /out:sample.exe stdstr.cs";
compiler.StartInfo.UseShellExecute = false;
compiler.StartInfo.RedirectStandardOutput = true;
compiler.Start();
Console.WriteLine(compiler.StandardOutput.ReadToEnd());
compiler.WaitForExit();
Это немного улучшилось по сравнению с принятым ответом от @mdb. В частности, мы также фиксируем вывод ошибки процесса. Кроме того, мы фиксируем эти результаты через события, потому что ReadToEnd() не работает, если вы хотите фиксировать как ошибку, так и регулярный вывод. Мне понадобилось время, чтобы выполнить эту работу, потому что на самом деле также требуются вызовы BeginxxxReadLine() после Start().
using System.Diagnostics;
Process process = new Process();
void LaunchProcess()
{
process.EnableRaisingEvents = true;
process.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(process_OutputDataReceived);
process.ErrorDataReceived += new System.Diagnostics.DataReceivedEventHandler(process_ErrorDataReceived);
process.Exited += new System.EventHandler(process_Exited);
process.StartInfo.FileName = "some.exe";
process.StartInfo.Arguments = "param1 param2"
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
process.Start();
process.BeginErrorReadLine();
process.BeginOutputReadLine();
//below line is optional if we want a blocking call
//process.WaitForExit();
}
void process_Exited(object sender, EventArgs e)
{
Console.WriteLine(string.Format("process exited with code {0}\n", process.ExitCode.ToString()));
}
void process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
Console.WriteLine(e.Data + "\n");
}
void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
Console.WriteLine(e.Data + "\n");
}
Используйте ProcessInfo.RedirectStandardOutput для перенаправления вывода при создании консольного процесса.
Затем вы можете использовать Process.StandardOutput, чтобы прочитать выход программы.
Во второй ссылке есть пример кода, как это сделать.
ConsoleAppLauncher - это библиотека с открытым исходным кодом, специально предназначенная для ответа на этот вопрос. Он захватывает все выходные данные, созданные в консоли, и предоставляет простой интерфейс для запуска и закрытия консольного приложения.
Событие ConsoleOutput запускается каждый раз, когда новая строка записывается консолью в стандартный/вывод ошибки. Строки поставлены в очередь и гарантированно соответствуют порядку вывода.
Также доступен как пакет NuGet.
Образец вызова для получения полного вывода консоли:
// Run simplest shell command and return its output.
public static string GetWindowsVersion()
{
return ConsoleApp.Run("cmd", "/c ver").Output.Trim();
}
Пример с живой обратной связью:
// Run ping.exe asynchronously and return roundtrip times back to the caller in a callback
public static void PingUrl(string url, Action<string> replyHandler)
{
var regex = new Regex("(time=|Average = )(?<time>.*?ms)", RegexOptions.Compiled);
var app = new ConsoleApp("ping", url);
app.ConsoleOutput += (o, args) =>
{
var match = regex.Match(args.Line);
if (match.Success)
{
var roundtripTime = match.Groups["time"].Value;
replyHandler(roundtripTime);
}
};
app.Run();
}
Я добавил несколько вспомогательных методов в O2 Platform (проект с открытым исходным кодом), которые позволяют вам легко script взаимодействовать с другой процесс через консольный вывод и ввод (см. http://code.google.com/p/o2platform/source/browse/trunk/O2_Scripts/APIs/Windows/CmdExe/CmdExeAPI.cs)
Также полезно использовать API, который позволяет просматривать вывод консоли текущего процесса (в существующем элементе управления или всплывающем окне). См. Это сообщение в блоге для более подробной информации: http://o2platform.wordpress.com/2011/11/26/api_consoleout-cs-inprocess-capture-of-the-console-output/ (этот блог также содержит сведения о том, как использовать консольный вывод новых процессов)
Добавлено process.StartInfo.**CreateNoWindow** = true;
и timeout
.
private static void CaptureConsoleAppOutput(string exeName, string arguments, int timeoutMilliseconds, out int exitCode, out string output)
{
using (Process process = new Process())
{
process.StartInfo.FileName = exeName;
process.StartInfo.Arguments = arguments;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = true;
process.Start();
output = process.StandardOutput.ReadToEnd();
bool exited = process.WaitForExit(timeoutMilliseconds);
if (exited)
{
exitCode = process.ExitCode;
}
else
{
exitCode = -1;
}
}
}
Из PythonTR - Python Programcıları Derneği, e-kitap, örnek:
Process p = new Process(); // Create new object
p.StartInfo.UseShellExecute = false; // Do not use shell
p.StartInfo.RedirectStandardOutput = true; // Redirect output
p.StartInfo.FileName = "c:\\python26\\python.exe"; // Path of our Python compiler
p.StartInfo.Arguments = "c:\\python26\\Hello_C_Python.py"; // Path of the .py to be executed