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