Перенаправить консольный вывод в текстовое поле в отдельной программе - PullRequest
49 голосов
/ 06 января 2009

Я разрабатываю приложение для Windows Forms, которое требует от меня вызова отдельной программы для выполнения задачи. Программа является консольным приложением, и мне нужно перенаправить стандартный вывод из консоли в TextBox в моей программе.

У меня нет проблем с запуском программы из моего приложения, но я не знаю, как перенаправить вывод в мое приложение. Мне нужно захватить вывод, пока программа работает с использованием событий.

Консольная программа не должна останавливаться, пока мое приложение не остановится и текст не будет постоянно меняться через случайные интервалы. То, что я пытаюсь сделать, это просто перехватить вывод из консоли, чтобы вызвать обработчик событий, который затем можно использовать для обновления TextBox.

Я использую C # для кодирования программы и использую .NET Framework для разработки. Исходное приложение не является программой .NET.

EDIT: Вот пример кода того, что я пытаюсь сделать. В моем последнем приложении я заменю Console.WriteLine кодом для обновления TextBox. Я попытался установить точку останова в своем обработчике событий, но она даже не достигнута.

    void Method()
    {
        var p = new Process();
        var path = @"C:\ConsoleApp.exe";

        p.StartInfo.FileName = path;
        p.StartInfo.UseShellExecute = false;
        p.OutputDataReceived += p_OutputDataReceived;

        p.Start();
    }

    static void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        Console.WriteLine(">>> {0}", e.Data);
    }

Ответы [ 5 ]

70 голосов
/ 06 января 2009

Это работает для меня:

void RunWithRedirect(string cmdPath)
{
    var proc = new Process();
    proc.StartInfo.FileName = cmdPath;

    // set up output redirection
    proc.StartInfo.RedirectStandardOutput = true;
    proc.StartInfo.RedirectStandardError = true;    
    proc.EnableRaisingEvents = true;
    proc.StartInfo.CreateNoWindow = true;
    // see below for output handler
    proc.ErrorDataReceived += proc_DataReceived;
    proc.OutputDataReceived += proc_DataReceived;

    proc.Start();

    proc.BeginErrorReadLine();
    proc.BeginOutputReadLine();

    proc.WaitForExit();
}

void proc_DataReceived(object sender, DataReceivedEventArgs e)
{
    // output will be in string e.Data
}
4 голосов
/ 06 января 2009

Вы можете использовать следующий код

        MemoryStream mem = new MemoryStream(1000);
        StreamWriter writer = new StreamWriter(mem);
        Console.SetOut(writer);

        Assembly assembly = Assembly.LoadFrom(@"C:\ConsoleApp.exe");
        assembly.EntryPoint.Invoke(null, null);
        writer.Close();

        string s = Encoding.Default.GetString(mem.ToArray());
        mem.Close();
1 голос
/ 26 ноября 2011

Я добавил несколько вспомогательных методов к платформе O2 (проект с открытым исходным кодом), которые позволяют легко создавать сценарии взаимодействия с другим процессом через консольный вывод и ввод (см. * 1004). *

Также полезным может быть API, который позволяет просматривать вывод консоли текущего процесса (в существующем элементе управления или всплывающем окне). См. Этот пост в блоге для получения более подробной информации:

http://o2platform.wordpress.com/2011/11/26/api_consoleout-cs-inprocess-capture-of-the-console-output/ (этот блог также содержит подробности о том, как использовать вывод консоли новых процессов)

1 голос
/ 06 января 2009
0 голосов
/ 17 февраля 2015

Спасибо Марку Максэму за ответ, который сэкономил мне время!

Как заметил Jon of All Trades, UseShellExecute должен быть установлен в false для перенаправления потоков ввода-вывода, в противном случае вызов Start() выдает InvalidOperationException.

Вот моя модификация кода, где txtOut - это текстовое поле только для чтения WPF

void RunWithRedirect(string cmdargs)
{
    var proc = new Process()
    {
        StartInfo = new ProcessStartInfo("cmd.exe", "/k " + cmdargs)
        {
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            CreateNoWindow = true
        },
        EnableRaisingEvents = true
    };

    // see below for output handler
    proc.ErrorDataReceived += proc_DataReceived;
    proc.OutputDataReceived += proc_DataReceived;
    proc.Start();

    proc.BeginErrorReadLine();
    proc.BeginOutputReadLine();

    proc.WaitForExit();
}

void proc_DataReceived(object sender, DataReceivedEventArgs e)
{
    if (e.Data != null)
        Dispatcher.BeginInvoke(new Action( () => txtOut.Text += (Environment.NewLine + e.Data) ));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...