2017-10-08 257 views
0

我目前正在尝试读取CMD文件的内容,它正在工作,但它不会将文本追加到文本框,直到cmd关闭。 此.BAT文件用于启动和管理服务器,以便cmd内容不断更新。 如果我关闭了cmd文件,它会关闭服务器,我们不希望那样做,因为那样会很好,服务器需要运行。 这是困境。如何读取Process.StandardOutput属性异步?

它不会将文本追加到文本框直到cmd关闭。

我试着把它放在一个后台工作器中,并运行它异步但它做同样的事情。 我如何阅读流程? StandardOutput属性异步,所以我不会陷入僵局?

using System; 
using System.ComponentModel; 
using System.Diagnostics; 
using System.Linq; 
using System.Windows.Forms; 
using System.IO; 

namespace SendInput 
{ 
    public partial class Form1: Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 
     StreamReader outputReader = null; 
     StreamReader errorReader = null; 

     private void btnCommand_Click(object sender, EventArgs e) 
     { 
      CheckForIllegalCrossThreadCalls = false; 

      backgroundWorker1.RunWorkerAsync(); 
     } 

     private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
     { 
      try 
      { 
       //Create Process Start information 
       ProcessStartInfo processStartInfo = 
        new ProcessStartInfo(@"C:\Users\devPC\Desktop\Server\run.bat"); 
       processStartInfo.ErrorDialog = false; 
       processStartInfo.UseShellExecute = false; 
       processStartInfo.RedirectStandardError = true; 
       processStartInfo.RedirectStandardInput = true; 
       processStartInfo.RedirectStandardOutput = true; 

       //Execute the process 
       Process process = new Process(); 
       process.StartInfo = processStartInfo; 
       bool processStarted = process.Start(); 
       if (processStarted) 
       { 
        //Get the output stream 
        outputReader = process.StandardOutput; 
        errorReader = process.StandardError; 

        //Display the result 
        string displayText = "Output \n==============\n"; 
        displayText += outputReader.ReadToEnd(); 
        displayText += "\nError\n==============\n"; 
        displayText += errorReader.ReadToEnd(); 
        rtbConsole.Text = displayText; 
       } 
       process.WaitForExit(); 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.Message); 
      } 
     } 
    } 
} 

回答

0

这使用异步/等待来启动进程,然后使用进程输出事件来更新UI。

using System; 
using System.ComponentModel; 
using System.Diagnostics; 
using System.Linq; 
using System.Windows.Forms; 
using System.IO; 

namespace SendInput 
{ 
    public partial class Form1: Form 
    { 
     private SynchronizationContext _syncContext; 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private async void btnCommand_Click(object sender, EventArgs e) 
     { 
      CheckForIllegalCrossThreadCalls = false; 

      await StartProcessAsync(); 
     } 

     private Task StartProcessAsync() 
     { 
      return Task.Run(()=> 
      { 
       try 
       { 
        //Create Process Start information 
        ProcessStartInfo processStartInfo = 
         new ProcessStartInfo(@"C:\Users\devPC\Desktop\Server\run.bat"); 
        processStartInfo.ErrorDialog = false; 
        processStartInfo.UseShellExecute = false; 
        processStartInfo.RedirectStandardError = true; 
        processStartInfo.RedirectStandardInput = true; 
        processStartInfo.RedirectStandardOutput = true; 

        //Execute the process 
        Process process = new Process(); 
        process.StartInfo = processStartInfo; 

        process.OutputDataReceived += (sender, args) => UpdateText(args.Data); 
        process.ErrorDataReceived += (sender, args) => UpdateErrorText(args.Data); 

        process.Start(); 
        process.BeginOutputReadLine(); 
        process.BeginErrorReadLine(); 
        process.WaitForExit(); 
       } 
       catch (Exception ex) 
       { 
        MessageBox.Show(ex.Message); 
       } 
      }); 
     } 

     private void UpdateText(string outputText) 
     { 
      _syncContext.Post(x => rtbConsole.AppendText("Output \n==============\n"), null);     
      _syncContext.Post(x => rtbConsole.AppendText(outputText), null); 
     } 

     private void UpdateErrorText(string outputErrorText) 
     { 
      _syncContext.Post(x => rtbConsole.AppendText("\nError\n==============\n"), null); 
      _syncContext.Post(x => rtbConsole.AppendText(outputErrorText), null); 
     } 
    } 
}