2011-08-19 7 views
5

Tôi đang viết một ứng dụng winform C# bắt đầu quá trình thứ hai để thực hiện các lệnh shell như "dir" và "ping". Tôi chuyển hướng đầu ra của quá trình thứ hai để ứng dụng của tôi có thể nhận được kết quả lệnh. Nó gần như hoạt động tốt.C#: lấy dòng kết quả lệnh shell bên ngoài theo dòng

Vấn đề duy nhất là ứng dụng winform của tôi nhận được kết quả đầu ra của dòng lệnh thay vì từng dòng một. Ví dụ, nó phải đợi lệnh "ping" bên ngoài kết thúc (mất nhiều giây hoặc lâu hơn) và sau đó nhận được toàn bộ đầu ra (nhiều dòng) cùng một lúc.

Điều tôi muốn là ứng dụng nhận được kết quả đầu ra cmdline theo thời gian thực, tức là theo các dòng không theo khối. Điều này có thể thực hiện được không?

Tôi đang sử dụng mã này để đọc kết quả: while (! (Result = proc.StandardOutput.ReadLine()) = null)

Nhưng nó không làm việc theo cách tôi mong đợi. Cảm ơn trước.

EDIT: đây là mã Tôi đang sử dụng:

System.Diagnostics.ProcessStartInfo procStartInfo = new 
      System.Diagnostics.ProcessStartInfo("cmd", "/c " + command); 

    procStartInfo.WindowStyle = ProcessWindowStyle.Hidden; 

    // The following commands are needed to redirect the standard output. 
    procStartInfo.RedirectStandardOutput = true; 
    procStartInfo.UseShellExecute = false; 
    procStartInfo.CreateNoWindow = true; 
    // Now we create a process, assign its ProcessStartInfo and start it 
    System.Diagnostics.Process proc = new System.Diagnostics.Process(); 
    proc.StartInfo = procStartInfo; 
    proc.Start(); 

    // Get the output into a string 
    string result; 
    try { 
     while ((result = proc.StandardOutput.ReadLine()) != null) 
     { 
      AppendRtfText(result+"\n", Brushes.Black); 
     } 
    } // here I expect it to update the text box line by line in real time 
     // but it does not. 
+1

[có thể trùng lặp] (http://stackoverflow.com/questions/ 415620/redirect-console-output-to-textbox-in-riêng-chương trình-c) –

+0

Hiển thị mã bạn đã thử sẽ hữu ích. –

Trả lời

3

Hãy xem ví dụ tại this msdn article về cách đọc hoàn toàn không đồng bộ.

Ngoài ra tôi mong đợi mã của bạn không đọc từng dòng bây giờ nhưng giao diện người dùng không nhận được bất cứ lúc nào để sơn lại (thiếu Application.DoEvents(); sau khi cập nhật RTFTextBox

+0

Thanks @Eddy, bạn nói đúng. Nhưng DoEvents() không có sẵn trong WPF. Tôi đã sử dụng giải pháp này: http://stackoverflow.com/questions/4502037/where-is-the-application-doevents-in-wpf – Charlie

2

Thay vì vòng lặp sử dụng while ((result = proc.StandardOutput.ReadLine()) != null) bạn nên sử dụng:

... 
proc.OutputDataReceived += proc_DataReceived; 
proc.Start(); 
proc.BeginOutputReadLine(); 
proc.WaitForExit(); 

này sẽ bắt đầu đồng bộ đọc những dòng khi họ đến, bạn sau đó xử lý các dòng được đọc bởi e.Data trong bộ xử lý proc_DataReceived, vì bạn đang sử dụng BeginOutputReadline, e.Data sẽ là một chuỗi ký tự.

0

tôi đã cùng một vấn đề và nhận được xung quanh nó như sau. tôi thấy rằng nếu tôi đã có một lỗi trong ứng dụng bên ngoài tôi đã nhận được không có đầu ra ở tất cả các sử dụng phương pháp ReadToEnd(), do đó, chuyển sang sử dụng dòng bởi streamreader. Sẽ được chuyển sang sử dụng câu trả lời được cung cấp bởi Saa'd mặc dù nó trông giống như cách thích hợp để xử lý nó.

Cũng tìm thấy giải pháp này: c# coding convention public/private contexts cung cấp để xử lý lỗi cùng một lúc và đưa ra một lời giải thích đầy đủ hơn đến việc sử dụng externalApp.OutputDataReceived += (sender, args) => Console.WriteLine(args.Data);

Process externalApp = new Process(); 
     externalApp.StartInfo.FileName = config.ExternalApps + @"\location\DeleteApp.exe"; 
     externalApp.StartInfo.Arguments = Directory.GetCurrentDirectory() + @"\..\..\..\project\argumentsForDeleteApp.xml"; 
     externalApp.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
     externalApp.StartInfo.UseShellExecute = false; 
     externalApp.StartInfo.RedirectStandardOutput = true; 
     Console.Out.WriteLine(DateTime.UtcNow.ToLocalTime().ToString() + 
      ":###### External app: " + externalApp.StartInfo.FileName + " -  START"); 
     externalApp.Start(); 
     using (StreamReader reader = externalApp.StandardOutput) 
     { 
      while (!reader.EndOfStream) 
      { 
       string result = reader.ReadLine(); 
       Console.Out.WriteLine(result); 
      } 
     } 
     externalApp.WaitForExit();