C# 重定向读取ansys的bat运行文件

牵扯到的概念有多线程异步读取,和control的beginInvoke的概念

主要讲述怎样在多线程里面运行后,然后更改UI。

先贴上代码:

代码参考了C#多线程

public class TestRun
    {
        static string runCommand = @;C:\Users\Administrator\Desktop\ansys 1\ansys.bat;
        public Process process = new Process();

        public void RunBat()
        {
            FileInfo file = new FileInfo(runCommand);
            process.StartInfo = new ProcessStartInfo();
            process.StartInfo.FileName = runCommand;
            process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.WorkingDirectory = file.DirectoryName;
            process.Start();
            process.BeginOutputReadLine();

            process.WaitForExit();

            process.CancelOutputRead();
            process.Close();  
        }
      
    }

其中的Process的属性设置请参照:

C#控制台输出实时重定向

C#输入输出重定向

在窗口Form类里面,定义TestRun类

public partial class Form1 : Form
    {
        TestRun testRun = new TestRun();

        private Thread thread1;
        delegate void set_Text(string s);
        set_Text Set_Text;



        public Form1()
        {
            InitializeComponent();

            Set_Text = new set_Text(DisplayOutput);

            this.testRun.process.OutputDataReceived
                 += new System.Diagnostics.DataReceivedEventHandler(process_OutputDataReceived);
        }

        private void button1_Click(object sender, EventArgs e)
        {

            thread1 = new Thread(new ThreadStart(this.testRun.RunBat));
            thread1.Start();
            
        }

其中窗口类的构造函数里面,OutputDataReceived是进程process的一个事件,订阅了事件处理程序process_OutputDataReceived

OutputDataReceived 事件指示关联的 Process 已写入其重定向 StandardOutput 流中。

该事件在对 StandardOutput 执行异步读取操作期间启用。若要启动异步读取操作,必须重定向 Process 的 StandardOutput 流,向 OutputDataReceived 事件添加事件处理程序,并调用 BeginOutputReadLine。之后,每当该进程向重定向 StandardOutput 流中写入一行时,OutputDataReceived 事件都会发出信号,直到该进程退出或调用 CancelOutputRead 为止。

可参考MSDN的介绍。

private void DisplayOutput(string s)
        {

            if ((s) != null)
            {
                this.ResultTxtBox.AppendText(s + "\r\n");
                this.ResultTxtBox.SelectionStart = this.ResultTxtBox.Text.Length;
                this.ResultTxtBox.ScrollToCaret();
            }
        }

此函数为delegate void set_Text(string s)的方法

public void process_OutputDataReceived(object sender, System.Diagnostics.DataReceivedEventArgs e)
        {
             
                if ((e.Data) != null)
                {
                    this.ResultTxtBox.BeginInvoke(Set_Text,new object[]{e.Data});

                }
        }

这个就是process的OutputDataReceived事件订阅的方法,其中用了BeginInvoke来更新主线程的UI,从其他线程直接引用控件会出现问题

关于BeginInvoke的用法网上很多,可以去查查