using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace AiControlRequest { /// /// 脚本执行类 /// lbf 2020/05/20 14:18 /// public abstract class ScriptExecutor { public DataReceivedEventHandler DataReceivedEvent; private ConcurrentQueue concurrentQueue = new ConcurrentQueue(); /// /// 执行脚本的命令 /// protected string ProcessName { get; set; } protected SynchronizationContext synchronizationContext = null; public event SendOrPostCallback ReceivedControlData; public ScriptExecutor(SynchronizationContext context,string ProcessName) { this.synchronizationContext = context; this.ProcessName = ProcessName; new Task(() => { DataReceivedEventArgs args; while (true) { if (this.concurrentQueue.TryDequeue(out args)) { // 为异步获取订阅事件 if (this.DataReceivedEvent != null) { this.DataReceivedEvent(this, args); } } else { Task.Delay(10); } } }).Start(); } /// /// 根据脚本返回结果分类数据 /// /// 界面接收数据控件 /// 异步返回数据 /// 控件分类数据 protected abstract ControlData produceControlData(Control control, DataReceivedEventArgs e); private void addDataReceivedEvent(Control control, string commandString) { if (DataReceivedEvent == null) { DataReceivedEvent += new DataReceivedEventHandler((sender1, e1) => { if (!string.IsNullOrEmpty(e1.Data)) { if (this.ReceivedControlData != null) { this.synchronizationContext.Post(this.ReceivedControlData, produceControlData(control,e1)); } } }); } } /// /// 执行脚本命令,结果会通过ReceivedControlData事件返回 /// /// 接收数据的控件 /// 执行的脚本命令 public void execute(Control control, string commandString) { addDataReceivedEvent(control, commandString); if (this.ReceivedControlData != null) { this.synchronizationContext.Post(this.ReceivedControlData, new ControlData { Control = control, CallbackDataType = CallbackDataType.Command, DataString = commandString }); } this.executeScript(commandString); } public void DataReceivedEventHandler(object sender, DataReceivedEventArgs e) { //push into queue this.concurrentQueue.Enqueue(e); } /// /// 执行脚本,脚本返回数据在OutputDataReceived数据中返回,调用都需要挂载OutputDataReceived事件接收返回数据 /// /// 脚本进程名 /// 要执行的脚本文件+参数 private void executeScript( string commandString) { ProcessStartInfo start = new ProcessStartInfo(); start.FileName = this.ProcessName; start.Arguments = commandString; start.UseShellExecute = false; start.RedirectStandardOutput = true; start.RedirectStandardInput = true; start.RedirectStandardError = true; start.CreateNoWindow = true; using (Process p = Process.Start(start)) { // 异步获取命令行内容 p.BeginOutputReadLine(); // 为异步获取订阅事件 if (this.DataReceivedEvent != null) { p.OutputDataReceived += DataReceivedEventHandler; ; } } } } }