如何阅读Process.StandardOutput属性异步?

时间:2017-10-08 06:12:05

标签: c# batch-file asynchronous cmd

我目前正在尝试阅读CMD文件的内容并且它正常工作,但在cmd关闭之前,它不会将文本附加到文本框中。 此.BAT文件用于启动和管理服务器,因此cmd内容会不断更新。 如果我关闭cmd文件,它会关闭服务器而我们不希望这样,因为这将是非常好的,服务器需要运行。 这就是困境。

在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);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

这使用async / await启动进程,然后使用进程输出事件来更新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);
        }
    }
}