process.standardoutput.ReadToEnd () всегда пустой? - PullRequest
12 голосов
/ 06 января 2010

Я запускаю консольное приложение, но когда я перенаправляю стандартный вывод, я всегда ничего не получаю!

Когда я не перенаправляю его и устанавливаю CreateNoWindow на false, я все правильно вижу в консоли, но когда я перенаправляю его, StandardOutput.ReadToEnd() всегда возвращает пустую строку.

        Process cproc = new Process();
        cproc.StartInfo.CreateNoWindow = true;
        cproc.StartInfo.FileName = Dest;
        cproc.StartInfo.RedirectStandardOutput = true;
        cproc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
        cproc.StartInfo.UseShellExecute = false;
        cproc.EnableRaisingEvents = true;
        cproc.Start();
        cproc.Exited += new EventHandler(cproc_Exited);
        while(!stop)
        {
           result += cproc.StandardOutput.ReadToEnd();
        }

EventHandler cproc_exited просто устанавливает stop на true. Может кто-нибудь объяснить, почему result всегда string.Empty?

Ответы [ 4 ]

15 голосов
/ 04 ноября 2010

Лучший способ для этого - перенаправить вывод и дождаться событий:

    // not sure if all this flags are needed
    process.StartInfo.CreateNoWindow = true;
    process.StartInfo.ErrorDialog = false;
    process.StartInfo.UseShellExecute = false;
    process.StartInfo.RedirectStandardError = true;
    process.StartInfo.RedirectStandardInput = true;
    process.StartInfo.RedirectStandardOutput = true;
    process.EnableRaisingEvents = true;
    process.OutputDataReceived += process_OutputDataReceived;
    process.ErrorDataReceived += process_ErrorDataReceived;
    process.Exited += process_Exited;
    process.Start();

    void process_Exited(object sender, System.EventArgs e)
    {
        // do something when process terminates;
    }

    void process_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        // a line is writen to the out stream. you can use it like:
        string s = e.Data;
    }

    void process_ErrorDataReceived(object sender, DataReceivedEventArgs e)
    {
        // a line is writen to the out stream. you can use it like:
        string s = e.Data;
    }
8 голосов
/ 06 января 2010

Почему ты зациклен? Как только он будет прочитан до конца, он больше не сможет читать данные, не так ли?

Вы уверены, что текст на самом деле записывается в StandardOutput, а не StandardError?

(И да, очевидно, вы хотите установить для RedirectStandardOutput значение true, а не false. Я предположил, что это был случай, когда вы копировали неверную версию своего кода.)

РЕДАКТИРОВАТЬ: Как я советовал в комментариях, вы должны читать из стандартного вывода и стандартной ошибки в отдельных потоках. не дождитесь завершения процесса - это может привести к тупику, когда вы ожидаете завершения процесса, но процесс блокируется, пытаясь записать в stderr / stdout, поскольку читать из буфера.

Либо вы можете подписаться на события OutputDataReceived и ErrorDataReceived, чтобы избежать использования дополнительных потоков.

7 голосов
/ 06 января 2010

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

cproc.StartInfo.RedirectStandardOutput = false;

в

cproc.StartInfo.RedirectStandardOutput = true;

Работает ли для вас следующий образец из MSDN ?

// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "Write500Lines.exe";
p.Start();
// Do not wait for the child process to exit before
// reading to the end of its redirected stream.
// p.WaitForExit();
// Read the output stream first and then wait.
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
0 голосов
/ 06 января 2010

Избавьтесь от петли и переведите вызов на ReadToEnd на cproc_Exited.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...