using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using NUnit.Framework;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace AiControlRequest
{
///
/// Python脚本执行类
/// lbf 2020/05/20 14:43
///
public class PythonExecutor :ScriptExecutor
{
///
/// IBM组织识别、标准评级py脚本文件
///
public string IbmAiPy { get; set; }
private readonly string ReturnDataPrefix = "AI_result";//"{\"content\":";
private readonly string ParameterErrorPrefix = "AI_error:";
private readonly string ProgressPrefix = "AI_progress:";
private readonly int ARGUMENTS_MAX_LENGTH = 1024 * 32;//命令行参数最大长度
///
/// python执行器,返回数据更新界面控件
///
/// 界面UI环境
public PythonExecutor(SynchronizationContext context):base(context,"python")
{
this.IbmAiPy = @"D:\vi\vi_server\ibm_ai.py ";
}
///
/// python执行器,返回数据更新界面控件
///
/// 界面UI环境
/// 要执行的python脚本文件全路径
public PythonExecutor(SynchronizationContext context,string pyFilePath) : base(context, "python")
{
this.IbmAiPy = pyFilePath;
}
///
/// 停止后台脚本运行
///
public void stop()
{
lock(this.IbmAiPy)
{
string stop_file = Path.Combine(Path.GetDirectoryName(this.IbmAiPy), "stop.ai");
if (!System.IO.File.Exists(stop_file))
{
System.IO.File.Create(stop_file);
}
}
}
///
/// 执行python文件脚本
///
/// 回调界面控件
/// 要执行的python脚本文件全路径
/// 参数
public void executePy(Control control, params string[] parameters)
{
StringBuilder stringBuilder = new StringBuilder(256);
stringBuilder.Append(this.IbmAiPy);
if (parameters != null)
{
foreach (var parameter in parameters)
{
stringBuilder.Append(" \"");
stringBuilder.Append(parameter.Replace("'", "\\\"").Replace("\"", "\\\""));
stringBuilder.Append("\" ");
}
}
execute(control, stringBuilder.ToString());
}
///
/// 标准评级python接口调用,需要挂载ReceivedControlData接收返回值
///
/// 回调显示控件
/// 评级钢种ID
/// 检测项目ID
/// 其他参数
/// 等检测项目图像文件全名列表
public void ibmBzpj(Control control,string catagory,string items,object detectParams, List jpgFileList)
{
Assert.IsNotNull(jpgFileList);
Assert.IsNotEmpty(jpgFileList);
Hashtable json = new Hashtable();
json.Add("func", "bzpj");
json.Add("catagory", catagory);
json.Add("items", items);
json.Add("path", Path.GetDirectoryName(jpgFileList[0]).Replace("\\", "/"));
json.Add("images", string.Join(";", jpgFileList.Select(s => Path.GetFileName(s))));
string arguments = JsonConvert.SerializeObject(json).Replace("\"", "\\\"");
Assert.Less(Encoding.UTF8.GetBytes(arguments).Length, this.ARGUMENTS_MAX_LENGTH);
string commandString;
string vp = null;
if (detectParams != null)
{
if (detectParams.GetType() == typeof(string))
{
vp = detectParams.ToString().Replace("'", "\\\"");
}
else
{
vp = JsonConvert.SerializeObject(detectParams).Replace("\"", "\\\"");
}
}
if (!string.IsNullOrEmpty(vp))
{
commandString = string.Format("{0} \"{1}\" \"{2}\"", this.IbmAiPy, arguments, vp);
}
else
{
commandString = string.Format("{0} \"{1}\"", this.IbmAiPy, arguments);
}
execute(control, commandString);
}
///
/// IBM组织识别python接口调用,需要挂载ReceivedControlData接收返回值
///
/// 回调显示控件
/// 其他参数
/// 等检测项目图像文件全名列表
public void ibmZzsb(Control control, object detectParams, List jpgFileList)
{
Assert.IsNotNull(jpgFileList);
Assert.IsNotEmpty(jpgFileList);
Hashtable json = new Hashtable();
json.Add("catagory", "-1");
json.Add("status", "-1");
json.Add("magnification", "-1");
json.Add("func", "zzsb");
json.Add("path", Path.GetDirectoryName(jpgFileList[0]).Replace("\\", "/"));
json.Add("images", string.Join(";", jpgFileList.Select(s => Path.GetFileName(s))));
string arguments = JsonConvert.SerializeObject(json).Replace("\"", "\\\"");
Assert.Less(Encoding.UTF8.GetBytes(arguments).Length,this.ARGUMENTS_MAX_LENGTH);
string commandString;
if (detectParams != null && !string.IsNullOrEmpty(detectParams.ToString()))
{
commandString = string.Format("{0} \"{1}\" \"{2}\"", this.IbmAiPy, arguments,detectParams.ToString().Replace("'", "\\\""));
}
else
{
commandString = string.Format("{0} \"{1}\"", this.IbmAiPy, arguments);
}
execute(control, commandString);
}
///
/// 返回数据开头信息确认是什么类型数据,分为返回结果、一般信息、参数错误信息、执行的脚本命令
///
///
///
///
override
protected ControlData produceControlData(Control control, DataReceivedEventArgs e)
{
ControlData controlData = new ControlData { Control = control };
//不同类型返回数据
if (e.Data.Contains(this.ReturnDataPrefix))
{
controlData.DataString = e.Data.Substring(e.Data.IndexOf(this.ReturnDataPrefix));
controlData.CallbackDataType= CallbackDataType.ReturnData;
int contentPos = controlData.DataString.IndexOf(',');
int indexPos = controlData.DataString.IndexOf(':');
if (contentPos >= 0)
{
controlData.Index = int.Parse(controlData.DataString.Substring(indexPos + 1, contentPos - indexPos - 1));
controlData.DataString = controlData.DataString.Substring(contentPos + 1);
}
else
{
controlData.DataString = controlData.DataString.Substring(indexPos + 1);
}
}
else if (e.Data.Contains(this.ParameterErrorPrefix))
{
controlData.DataString = e.Data.Substring(e.Data.IndexOf(this.ParameterErrorPrefix));
controlData.CallbackDataType = CallbackDataType.ParameterError;
}
else if (e.Data.Contains(this.ProgressPrefix))
{
controlData.DataString = e.Data.Substring(e.Data.IndexOf(this.ProgressPrefix));
controlData.CallbackDataType = CallbackDataType.Progress;
}
else
{
controlData.DataString = e.Data;
controlData.CallbackDataType = CallbackDataType.Info;
}
return controlData;
}
}
}