2013-09-23 1 views
2

Я пытаюсь перечислить поддерживаемые интерфейсы, на которых dumpcap.exe может собирать данные.Обработка стандартного вывода в C#, возвращающем пустую строку

Команда я хочу запустить, «dumpcap.exe -D»

В моей системе, это дает выход как: -

1. \Device\NPF_{1B627AA8-2A1D-4C90-B560-517CF71B33A5} (Intel(R) 825 
Network Connection) 
2. \Device\NPF_{7ECC4D31-DF17-49AB-960D-628D0580F3C6} (Microsoft) 

Я пытаюсь прочитать выше вывод по запуск той же команды из приложения WPF C#. У меня есть следующий код, чтобы сделать так: -

 Process proc = new Process(); 

     //set the path to dumpcap.exe (verified by me) 
     proc.StartInfo.FileName = "..\\..\\..\\..\\..\\Dumpcap\\dumpcap.exe"; 

     StringBuilder dumpcapArgs = new StringBuilder(); 

     dumpcapArgs.Append("-D"); 

     proc.StartInfo.Arguments = dumpcapArgs.ToString(); 
     proc.StartInfo.CreateNoWindow = true; 
     proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
     proc.StartInfo.RedirectStandardOutput = true; 
     proc.StartInfo.UseShellExecute = false; 

     proc.Start(); 

     while (!proc.StandardOutput.EndOfStream) 
     { 
      string line = proc.StandardOutput.ReadLine(); 
      MessageBox.Show(line); 

     } 

Когда я отладки, выполнение не идет в моем цикле в то время как у всех. StandardOutput уже находится в конце потока. Копая дальше в класс класса StandardOutput, я вижу много System.NotSupportedExceptions по длине, положению и т. Д.

Что, возможно, не так с вышеуказанным кодом?

Быстрого наблюдение

Я попробовал другой образец C# консольное приложение с помощью следующего кода:

 Process proc = new Process(); 

     proc.StartInfo.FileName = "C:\\Karan\\Dumpcap\\dumpcap.exe"; 
     proc.StartInfo.Arguments = "-D"; 
     proc.StartInfo.UseShellExecute = false; 
     proc.StartInfo.RedirectStandardOutput = true; 
     proc.Start(); 

     Console.WriteLine(proc.StandardOutput.ReadToEnd()); 

     proc.WaitForExit(); 

Это печатает вывод, как ожидалось!

Однако, если я пытаюсь прочитать стандартную выходную строку в строковой переменной, я получаю пустую строку.

Например, это возвращает мне пустую строку: -

 Process proc = new Process(); 

     proc.StartInfo.FileName = "C:\\Karan\\Dumpcap\\dumpcap.exe"; 
     proc.StartInfo.Arguments = "-D"; 
     proc.StartInfo.UseShellExecute = false; 
     proc.StartInfo.RedirectStandardOutput = true; 
     proc.Start(); 


     String output = proc.StandardOutput.ReadToEnd(); 


     proc.WaitForExit(); 

ответ

2

Вы никогда не начать этот процесс. Вы должны сделать это с помощью proc.Start();

Length, Position и подобные члены Stream не поддерживаются, так как поток, представляющий стандарт из консольного приложения неизвестно в длину и вперед только поток. Так что это нормально, а не ошибка в коде.

+0

К сожалению, я пропустил эту линию при копировании кода из Visual Studio. моя вина. Обновлено. – Karan

1

Попробуйте это:

string output = proc.StandardOutput.ReadToEnd(); 
proc.WaitForExit(); 

foreach(var line in output.Split('\r')) 
{ 
    MessageBox.Show(line); 
} 

Почему это работает? Потенциально нет ничего в потоке вывода при первом запросе EndOfStream. Это состояние гонки.

Я прочитал эту статью перед публикацией. Дайте ему читать http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardoutput.aspx

+1

Я все еще получаю пустую строку "" в окне сообщения. – Karan

+0

Быстрое наблюдение, обновленное в вопросе. – Karan

+0

Я думаю, что вы очень близки к моей проблеме.Я не могу получить вывод в переменной строк (он всегда приходит как пустой), но с использованием стандартного синхронного метода (readToEnd() и использования Console.WriteLine()) печатает ожидаемый результат. Я думаю, что это имеет какое-то отношение к ожиданию завершения процесса и заполнения буфера Console.Writeline() – Karan

2

У вас есть EnableRaisingEvents до true?

Я не уверен, если это будет делать трюк, так как я обычно делаю перенаправление выхода иначе:

private Process proc; 
private string procOutput = string.Empty; 

private void StartProc() 
{ 
    this.procOutput = string.Empty; 
    this.proc = new Process(); 
    ... 
    this.proc.StartInfo.UseShellExecute = false; 
    this.proc.StartInfo.CreateNoWindow = true; 
    this.proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 

    this.proc.EnableRaisingEvents = true; 
    this.proc.OutputDataReceived += this.ProcOutputDataReceivedHandler; 
    this.proc.Exited += this.ProcExitedHandler; 

    this.proc.Start(); 

    this.proc.BeginOutputReadLine(); 
} 

private void ProcOutputDataReceivedHandler(object sendingProcess, DataReceivedEventArgs e) 
{ 
    if (!string.IsNullOrEmpty(e.Data)) 
    { 
     this.procOutput += e.Data; 
    } 
} 

private void ProcExitedHandler(object sender, EventArgs e) 
{ 
    // Check the exitcode for possible errors happened during execution. 
    MessageBox.Show(this.procOutput); 
} 
+0

Я быстро обновил этот вопрос. – Karan

+0

Я пробовал ваш метод. Я не могу получить вывод в переменной строк (он всегда приходит как пустой), но с использованием стандартного синхронного метода (readToEnd() и использования Console.WriteLine()) печатает ожидаемый результат. – Karan

+0

Это странно. Можете ли вы установить контрольную точку в 'ProcOutputDataReceivedHandler', чтобы проверить, действительно ли она попадает, и если да, то что такое содержимое' e.Data'? – Koen

Смежные вопросы