You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1242 lines
53 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Mesnac.Basic;
using System.Xml;
using System.IO;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms;
using System.Reflection;
using System.Reflection.Emit;
using System.Configuration;
using ICSharpCode.Core;
using Host;
using Loader;
using Mesnac.Core;
using Mesnac.Core.Service;
using Mesnac.Controls.Default;
using Mesnac.Equips;
namespace Mesnac.Gui.Common
{
/// <summary>
/// 运行引擎类
/// </summary>
public class RunEngine
{
#region 字段定义
private string _projectPath = String.Empty; //组态工程路径
private AccidenceAnalyzer express; //表达式解析器
private TreeView _tree = null; //解析组态工程后的工程树
private Dictionary<string, Form> _runForms = new Dictionary<string, Form>(); //运行的组态画面列表
private bool _isLoad = false; //是否已载入工程
private bool _isControlPruview = false; //是否启用权限控制
#endregion
#region 属性定义
/// <summary>
/// 是否启用权限控制
/// </summary>
public bool IsControlPruview
{
get { return this._isControlPruview; }
}
#endregion
#region 单例实现
private static RunEngine _instance = null;
private RunEngine()
{
//注册表达式
this.express = new AccidenceAnalyzer();
this.express.OnAccidenceAnalysis += new AccidenceAnalyzer.AccidenceAnalysis(express_OnAccidenceAnalysis);
this.express.OnCallBack += new AccidenceAnalyzer.CallBack(express_OnCallBack);
}
public static RunEngine Instance
{
get
{
if (_instance == null)
{
_instance = new RunEngine();
}
return _instance;
}
}
#endregion
#region 组态工程树属性定义
public TreeView Tree
{
get
{
return this._tree;
}
}
#endregion
#region 1、运行引擎初始化相关方法
#region 运行引擎初始化
/// <summary>
/// 运行引擎初始化
/// </summary>
/// <param name="projectPath">工程路径</param>
/// <param name="isAutoRun">是否自动执行自启动Action</param>
public bool Init(string projectPath, bool isAutoRun, bool isControlPurview)
{
LoggingService.Debug("运行引擎初始化...");
this._projectPath = projectPath;
this._isControlPruview = isControlPurview;
return this.Reload(isAutoRun);
}
#endregion
#region 重新加载工程
/// <summary>
/// 重新加载工程
/// </summary>
/// <param name="isAutoRun">是否自动执行自启动Action</param>
public bool Reload(bool isAutoRun)
{
LoggingService.Info("工程文件路径:" + this._projectPath);
string projectFile = String.Empty;
string[] files = Directory.GetFiles(this._projectPath, "*.mprj", SearchOption.TopDirectoryOnly);
if (files != null && files.Length == 1)
{
projectFile = files[0];
}
if (!String.IsNullOrWhiteSpace(projectFile))
{
this._tree = new TreeView();
this._tree.LoadFromXml(projectFile); //载入工程文件
this.ResetProjectDataSourceFactory(); //重置数据源
}
else
{
LoggingService.Error("缺少工程文件(mprj)...让系统以超级用户方式运行...");
UserInfo.Instance.UserID = "-99";
UserInfo.Instance.UserName = "-99";
UserInfo.Instance.RoleID = "-99";
return false;
}
string wizardName = this._tree.Nodes[0].Tag as string; //获取工程类型
Mesnac.Basic.RunSchema.Instance.ProjectPath = this._projectPath; //设置组态工程文件路径
Mesnac.Basic.RunSchema.Instance.EventConfigPath = Path.Combine(Application.StartupPath, "Data", "EventConfig", wizardName); //设置事件处理配置文件路径
if (this._isLoad)
{
new System.Threading.Thread(new System.Threading.ThreadStart(delegate() { Factory.Instance.AllReadStop(); })).Start(); //重新载入时先异步把设备变量的读取停止
this._isLoad = false;
}
string equipConfigFile = String.Empty; //保存设备配置文件
TreeNode nodeDevices = this._tree.GetFirstNodeByNodeName(FixNodeName.NodeDeviceName);
if (nodeDevices != null)
{
equipConfigFile = Path.Combine(this._projectPath, nodeDevices.GetPathNoRoot()) + ".xml";
}
if (File.Exists(equipConfigFile))
{
Mesnac.Equips.Factory.Instance.ProjectWizardName = wizardName;
Mesnac.Equips.Factory.Instance.ConfigFile = equipConfigFile;
Mesnac.Equips.Factory.Instance.SetAllReadDataEvent(OnReadData);
Mesnac.Equips.Factory.Instance.SetAllExceptEvent(OnExceptData);
new System.Threading.Thread(new System.Threading.ThreadStart(delegate()
{
Mesnac.Equips.Factory.Instance.AllReadStart();
})).Start(); //异步启动设备读取线程
this._isLoad = true;
}
Mesnac.ActionService.Service.Instance.IniRuntimeAction(wizardName, isAutoRun);
return true;
}
#endregion
#region 获取工程数据源文件
/// <summary>
/// 获取工程数据源文件
/// </summary>
/// <returns></returns>
private string GetProjectDataSourceFile()
{
string fileName = String.Empty;
if (this._tree != null)
{
TreeNode node = this._tree.GetFirstNodeByNodeName(FixNodeName.NodeDataSourceName);
fileName = Path.Combine(this._projectPath, node.GetPathNoRoot()) + ".xml";
return fileName;
}
else
{
LoggingService.Debug("获取工程数据源文件失败,原因:工程面板未初始化!");
return String.Empty;
}
}
#endregion
#region 重置工程数据源工厂,从文件读取数据
/// <summary>
/// 重置工程数据源工厂,从文件读取数据
/// </summary>
private void ResetProjectDataSourceFactory(params CallBackDelegate[] callBack)
{
string fileName = this.GetProjectDataSourceFile();
if (!String.IsNullOrEmpty(fileName))
{
DataSourceFactory.Instance.RefreshDataFromFile(fileName, callBack);
}
}
#endregion
#endregion
#region 2、画面仿真主业务相关方法
#region 画面仿真方法
/// <summary>
/// 画面仿真方法
/// </summary>
/// <param name="node">要仿真的画面节点</param>
/// <param name="showType">画面显示方式Document、Form、Dialog</param>
public void Simulation(TreeNode node, FormShowType showType)
{
try
{
if (!this._isLoad)
{
LoggingService.Debug("运行引擎未初始化,或组态工程缺少设备文件...");
//LoggingService.Error("运行引擎未初始化... 请调用RunEngine.Init(string projectPath)进行初始化工作或缺少设备文件");
}
//防止跨线程访问控件报告异常
Control.CheckForIllegalCrossThreadCalls = false;
string fileName = Path.Combine(this._projectPath, node.GetPathNoRoot()) + ".xml";
//LoggingService.Debug(fileName);
if (!String.IsNullOrEmpty(fileName) && File.Exists(fileName))
{
FrmRunTemplate frm = null;
//LoggingService.Info(fileName);
#region 获取要呈现的画面
#region 清除已释放的窗体对象
if (this._runForms.ContainsKey(node.Name))
{
if (this._runForms[node.Name].IsDisposed)
{
this._runForms.Remove(node.Name);
}
}
#endregion
if (!this._runForms.ContainsKey(node.Name))
{
#region 清除已释放的窗体对象
string[] viewKeys = Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ViewContentDic.Keys.ToArray();
foreach (string key in viewKeys)
{
if ((Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ViewContentDic[key] as FrmRunTemplate).IsDisposed)
{
Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ViewContentDic.Remove(key);
}
}
#endregion
if (!Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ViewContentDic.ContainsKey(Path.GetFileNameWithoutExtension(fileName)))
{
#region 构建画面组件和组件属性、事件
Dictionary<string, ObjectDescriptor> dic = XmlHandler.ParseFormXml(fileName);
Host.HostSurfaceManager hsManager = Mesnac.Core.Service.MesnacServiceManager.Instance.HostSurfaceManager;
Host.HostControl hostControl = hsManager.LoadNewHost(fileName);
List<IComponent> components = hsManager.basicHostLoader.mComponents;
frm = new FrmRunTemplate();
this._runForms.Add(node.Name, frm);
if (components.Count > 0)
{
frm = CopyComponent(dic, components[0], frm) as FrmRunTemplate; //复制窗体属性
}
for (int i = 1; i < components.Count; i++)
{
Type t = components[i].GetType();
Component c = Activator.CreateInstance(t) as Component;
c = CopyComponent(dic, components[i], c);
string componentName = GetComponentName(components[i]);
if (c is Control)
{
Control parentControl = FindParentControl(dic, frm as Control, c as Control);
if (parentControl == null)
{
frm.Controls.Add(c as Control);
}
else
{
parentControl.Controls.Add(c as Control);
}
}
else
{
string siteName = c.Site.Name;
frm.Container.Add(c);
c.Site.Name = siteName;
}
BindEvent(c); //绑定事件
}
//释放资源
hostControl.Dispose();
System.GC.Collect();
BindEvent(frm);
frm.Disposed += new EventHandler(frm_Disposed); //仿真画面关闭时
#endregion
}
else
{
frm = Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ViewContentDic[Path.GetFileNameWithoutExtension(fileName)] as FrmRunTemplate;
}
}
else
{
frm = this._runForms[node.Name] as FrmRunTemplate;
}
#endregion
#region 画面呈现
switch (showType)
{
case FormShowType.Document: //文档显示
Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ShowView(Path.GetFileNameWithoutExtension(fileName), frm);
break;
case FormShowType.Form: //窗体显示
frm.Show();
break;
case FormShowType.Dialog: //对话框显示
frm.ShowDialog(Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench as Form);
break;
case FormShowType.MultiScreen: //多屏显示
Screen[] screens = Screen.AllScreens;
if (screens.Length > 1) //如果有多个显示器,显示在第二个显示器
{
foreach (Screen screen in screens)
{
if (!screen.Primary)
{
frm.ShowInTaskbar = false; //不在任务栏中显示
frm.Show();
frm.Left = screen.WorkingArea.Location.X;
frm.Top = screen.WorkingArea.Location.Y;
frm.WindowState = FormWindowState.Maximized;
frm.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
}
}
}
else
{
//如果只有一个显示器,以文档方式显示
Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ShowView(Path.GetFileNameWithoutExtension(fileName), frm);
}
break;
case FormShowType.FloatWindow: //浮动显示
Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ShowView(Path.GetFileNameWithoutExtension(fileName), frm, Mesnac.Docking.DockState.Float);
break;
}
#endregion
}
}
catch (Exception ex)
{
LoggingService.Error(ex.Message);
LoggingService.Error(ex.StackTrace);
}
}
#endregion
public void Run(string formFile, Panel panelControl)
{
TreeNode nodeForm = Tree.GetFirstNodeByNodeName(formFile);
Simulation(nodeForm, panelControl);
}
#region Panel画面仿真
/// <summary>
/// 画面仿真方法
/// </summary>
/// <param name="node">要仿真的画面节点</param>
/// <param name="showType">画面显示方式Document、Form、Dialog</param>
public void Simulation(TreeNode node, Panel panelControl)
{
try
{
lock (String.Empty)
{
if (!this._isLoad)
{
LoggingService.Debug("运行引擎未初始化,或组态工程缺少设备文件...");
}
//防止跨线程访问控件报告异常
Control.CheckForIllegalCrossThreadCalls = false;
string fileName = Path.Combine(this._projectPath, node.GetPathNoRoot()) + ".xml";
if (!String.IsNullOrEmpty(fileName) && File.Exists(fileName))
{
FrmRunTemplate frm = null;
if (this._runForms.ContainsKey(node.Name))
{
if (this._runForms[node.Name].IsDisposed)
{
this._runForms.Remove(node.Name);
}
}
if (!this._runForms.ContainsKey(node.Name))
{
Dictionary<string, ObjectDescriptor> dic = XmlHandler.ParseFormXml(fileName);
Host.HostSurfaceManager hsManager = Mesnac.Core.Service.MesnacServiceManager.Instance.HostSurfaceManager;
Host.HostControl hostControl = hsManager.LoadNewHost(fileName);
List<IComponent> components = hsManager.basicHostLoader.mComponents;
frm = new FrmRunTemplate();
this._runForms.Add(node.Name, frm);
if (components.Count > 0)
{
frm = CopyComponent(dic, components[0], frm) as FrmRunTemplate; //复制窗体属性
}
for (int i = 1; i < components.Count; i++)
{
Type t = components[i].GetType();
Component c = Activator.CreateInstance(t) as Component;
c = CopyComponent(dic, components[i], c);
string componentName = GetComponentName(components[i]);
if (c is Control)
{
Control parentControl = FindParentControl(dic, frm as Control, c as Control);
if (parentControl == null)
{
frm.Controls.Add(c as Control);
}
else
{
parentControl.Controls.Add(c as Control);
}
}
else
{
string siteName = c.Site.Name;
frm.Container.Add(c);
c.Site.Name = siteName;
}
BindEvent(c); //绑定事件
}
//释放资源
hostControl.Dispose();
System.GC.Collect();
BindEvent(frm);
frm.FormClosing += new FormClosingEventHandler(frm_Disposed); //仿真画面关闭时
}
else
{
frm = this._runForms[node.Name] as FrmRunTemplate;
}
if (frm.MCPurview)
{
FrmSysLogin login = new FrmSysLogin(frm, null);
if (login.ShowDialog() != DialogResult.OK)
return;
login.Close();
}
//隐藏窗口
//foreach (KeyValuePair<string, Form> item in this._runForms)
//{
// if (item.Key.ToLower() == "mainbottom" || item.Key.ToLower() == "sulfmointer" || item.Key.ToLower() == "maintop")
// continue;
// FrmRunTemplate frmhid = item.Value as FrmRunTemplate;
// //frmhid.Hide();
//}
frm.TopLevel = false;
frm.Dock = System.Windows.Forms.DockStyle.Fill;
frm.FormBorderStyle = FormBorderStyle.None;
panelControl.Controls.Add(frm);
frm.Show();
frm.BringToFront();
}
}
}
catch (Exception ex)
{
LoggingService.Error(ex.Message);
LoggingService.Error(ex.StackTrace);
}
}
#endregion
#region 仿真方法注释
/*
/// <summary>
/// 仿真方法
/// </summary>
public void Simulation(TreeNode node, bool isDialog)
{
try
{
if (!this._isLoad)
{
//LoggingService.Error("运行引擎未初始化... 请调用RunEngine.Init(string projectPath)进行初始化工作或缺少设备文件");
}
//防止跨线程访问控件报告异常
Control.CheckForIllegalCrossThreadCalls = false;
string fileName = Path.Combine(this._projectPath, node.GetPathNoRoot()) + ".xml";
//LoggingService.Debug(fileName);
if (!String.IsNullOrEmpty(fileName) && File.Exists(fileName))
{
FrmRunTemplate frm = null;
//LoggingService.Info(fileName);
if (!this._runForms.ContainsKey(node.Name))
{
if (!Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ViewContentDic.ContainsKey(Path.GetFileNameWithoutExtension(fileName)))
{
Dictionary<string, ObjectDescriptor> dic = XmlHandler.ParseFormXml(fileName);
Host.HostSurfaceManager hsManager = Mesnac.Core.Service.MesnacServiceManager.Instance.HostSurfaceManager;
Host.HostControl hostControl = hsManager.LoadNewHost(fileName);
List<IComponent> components = hsManager.basicHostLoader.mComponents;
frm = new FrmRunTemplate();
this._runForms.Add(node.Name, frm);
if (components.Count > 0)
{
frm = CopyComponent(dic, components[0], frm) as FrmRunTemplate; //复制窗体属性
}
for (int i = 1; i < components.Count; i++)
{
Type t = components[i].GetType();
Component c = Activator.CreateInstance(t) as Component;
c = CopyComponent(dic, components[i], c);
string componentName = GetComponentName(components[i]);
if (c is Control)
{
Control parentControl = FindParentControl(dic, frm as Control, c as Control);
if (parentControl == null)
{
frm.Controls.Add(c as Control);
}
else
{
parentControl.Controls.Add(c as Control);
}
}
else
{
string siteName = c.Site.Name;
frm.Container.Add(c);
c.Site.Name = siteName;
}
BindEvent(c); //绑定事件
}
//释放资源
hostControl.Dispose();
System.GC.Collect();
BindEvent(frm);
frm.FormClosing += new FormClosingEventHandler(frm_FormClosing); //仿真画面关闭时
}
else
{
frm = Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ViewContentDic[Path.GetFileNameWithoutExtension(fileName)] as FrmRunTemplate;
}
}
else
{
frm = this._runForms[node.Name] as FrmRunTemplate;
}
if (isDialog)
{
//frm.TopLevel = true;
//frm.AutoScroll = true;
frm.Show();
}
else
{
Mesnac.Gui.Workbench.WorkbenchSingleton.Workbench.ShowView(Path.GetFileNameWithoutExtension(fileName), frm);
}
}
}
catch (Exception ex)
{
LoggingService.Error(ex.Message);
LoggingService.Error(ex.StackTrace);
}
}
* */
#endregion
#region 递归获取窗体下的所有控件
/// <summary>
/// 获取窗体内的所有控件,包括子级
/// </summary>
/// <param name="frm"></param>
/// <returns></returns>
private static Control[] GetAllControlsByForm(Form frm)
{
List<Control> controlList = new List<Control>();
GetAllControlsByParentControl(controlList, frm);
return controlList.ToArray();
}
/// <summary>
/// 递归获取控件下的子级控件
/// </summary>
/// <param name="controlList"></param>
/// <param name="parentControl"></param>
private static void GetAllControlsByParentControl(List<Control> controlList, Control parentControl)
{
foreach (Control c in parentControl.Controls)
{
controlList.Add(c);
GetAllControlsByParentControl(controlList, c);
}
}
#endregion
#region 递归获取当前控件的父级控件
/// <summary>
/// 递归获取当前控件的父级控件
/// </summary>
/// <param name="dic">xml窗体文件中的ObjectDescriptor集合</param>
/// <param name="top">顶层控件一般是Form</param>
/// <param name="c">当前控件</param>
/// <returns>返回当前控件的父级控件</returns>
private static Control FindParentControl(Dictionary<string, ObjectDescriptor> dic, Control top, Control c)
{
string componentName = GetComponentName(c);
foreach (Control ct in top.Controls)
{
Control parent = FindParentControl(dic, ct, c);
if (parent != null)
{
return parent;
}
if (ct.Site != null && ct.Site.Name == dic[componentName].ParentName)
{
return ct;
}
}
return null;
}
#endregion
#region 复制组件属性
/// <summary>
/// 复制组件属性
/// </summary>
/// <param name="dic">xml窗体文件中的ObjectDescriptor集合</param>
/// <param name="source">源组件</param>
/// <param name="destination">目标组件</param>
/// <returns>返回复制完属性后的目标组件</returns>
private static Component CopyComponent(Dictionary<string, ObjectDescriptor> dic, IComponent source, IComponent destination)
{
Type t = source.GetType();
Component c = destination as Component;
//BindEvent(c); //绑定事件
if (source.Site != null)
{
if (c.Site == null)
{
c.Site = (new IDEContainer(source.Site.GetService(typeof(IDesignerHost)) as IDesignerHost)).CreateSite(c);
c.Site.Name = source.Site.Name;
}
else
{
c.Site.Name = source.Site.Name;
}
}
PropertyDescriptorCollection pdc = TypeDescriptor.GetProperties(source); //获取原组件的设计时属性集合
System.Reflection.PropertyInfo[] properties = t.GetProperties();
System.Reflection.FieldInfo[] fields = t.GetFields();
foreach (System.Reflection.FieldInfo f in fields)
{
if (f.Name == "isRuntime")
{
f.SetValue(c, true);
}
else
{
f.SetValue(c, f.GetValue(source));
}
}
string componentName = GetComponentName(source);
List<string> lstProperties = dic[componentName].Properties;
foreach (System.Reflection.PropertyInfo p in properties)
{
if (p.CanRead & p.CanWrite && lstProperties.Contains(p.Name))
{
PropertyDescriptor pd = pdc[p.Name];
p.SetValue(c, pd.GetValue(source), null);
}
else if (p.CanRead && lstProperties.Contains(p.Name) && typeof(IList).IsAssignableFrom(p.PropertyType))
{
//处理工具栏,菜单栏中项集合的属性
PropertyDescriptor pd = pdc[p.Name];
IList listSourceValue = pd.GetValue(source) as IList;
IList listDestinationValue = p.GetValue(c, null) as IList;
object[] objs = new object[listSourceValue.Count];
listSourceValue.CopyTo(objs, 0);
foreach (object obj in objs)
{
if (obj.GetType().IsPublic)
{
object instance = Activator.CreateInstance(obj.GetType());
instance = CopyComponent(dic, obj as Component, instance as Component);
listDestinationValue.Add(instance);
BindEvent(instance as Component); //绑定事件
}
}
}
}
return c;
}
#endregion
#region 获取组件名称
/// <summary>
/// 获取组件名称
/// </summary>
/// <param name="source">要获取名称的组件</param>
/// <returns>返回组件名称</returns>
private static string GetComponentName(IComponent source)
{
if (source.Site != null && !String.IsNullOrEmpty(source.Site.Name))
{
return source.Site.Name;
}
string componentInfo = source.ToString();
string componentName = String.Empty;
if (componentInfo.IndexOf("[") > 0)
{
componentName = componentInfo.Substring(0, componentInfo.IndexOf("[") - 1).Trim();
}
else if (componentInfo.IndexOf("{") > 0)
{
componentName = componentInfo.Substring(componentInfo.IndexOf("{") + 1, componentInfo.IndexOf("}") - componentInfo.IndexOf("{") - 1).Trim();
}
else
{
componentName = componentInfo;
}
return componentName;
}
#endregion
#region 为组件绑定事件
/// <summary>
/// 绑定事件
/// </summary>
/// <param name="o">要绑定事件的组件对象</param>
private static void BindEvent(Component o)
{
string t = o.GetType().Name;
XmlNode tmpXEventNode = PublicConfig.Instance.EventXmlDoc.SelectSingleNode(String.Format("Components/Component[@Name=\"{0}\"]", t));
if (tmpXEventNode != null)
{
XmlNodeList tmpXActionLst = tmpXEventNode.SelectNodes("Propertys/Property");
foreach (XmlNode node in tmpXActionLst)
{
System.Reflection.PropertyInfo propertyInfo = o.GetType().GetProperty(node.Attributes["Name"].Value); //获取事件名称属性
if (propertyInfo == null)
{
continue;
}
object actionList = propertyInfo.GetValue(o, null);
if (actionList != null)
{
List<Mesnac.Controls.Base.DesignAction> tmpActionList = actionList as List<Mesnac.Controls.Base.DesignAction>;
if (tmpActionList == null || tmpActionList.Count == 0)
{
continue; //如果控件的事件列表中没有绑定事件则不执行事件绑定
}
if (node.Attributes["ControlPropertyName"] == null) continue;
string eventId = node.Attributes["ControlPropertyName"].Value;//获取事件名称属性控制的事件属性
if (!String.IsNullOrEmpty(eventId))
{
System.Reflection.EventInfo eInfo = o.GetType().GetEvent(eventId);
if (eInfo != null)
{
if (o.GetType() == typeof(FrmRunTemplate))
{
if (RunEngine.Instance.IsControlPruview == false)
{
(o as FrmRunTemplate).MCPurview = RunEngine.Instance.IsControlPruview; //修改窗体的权限控制属性值,主要用于区分设计(不控制权限)和运行环境。
}
}
MCEventHandler eventProcessor = new MCEventHandler(o, actionList);
//MCEventHandler eventProcessor = new MCEventHandler(o, actionList, eventId);
Type handlerType = eInfo.EventHandlerType;
MethodInfo invokeMethod = handlerType.GetMethod("Invoke");
if (invokeMethod != null)
{
ParameterInfo[] parms = invokeMethod.GetParameters();
Type[] parmTypes = new Type[parms.Length];
for (int i = 0; i < parms.Length; i++)
{
parmTypes[i] = parms[i].ParameterType;
}
AssemblyName aName = new AssemblyName();
aName.Name = "DynamicTypes" + Guid.NewGuid().ToString(); //防止动态程序集重复
AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(aName,
AssemblyBuilderAccess.Run);
ModuleBuilder mb = ab.DefineDynamicModule(aName.Name);
string typeBuidlerName = "Handler" + Guid.NewGuid().ToString(); //防止动态类型定义重复
TypeBuilder tb = mb.DefineType(typeBuidlerName, TypeAttributes.Public);
string dynamicHandlerName = "DynamicHandler_" + Guid.NewGuid().ToString(); //防止同一控件的多个方法名称重复
MethodBuilder handler = tb.DefineMethod(dynamicHandlerName, MethodAttributes.Public, invokeMethod.ReturnType, parmTypes);
ILGenerator il = handler.GetILGenerator();
il.Emit(OpCodes.Ldstr, "触发调用");
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Ldarg_2);
il.Emit(OpCodes.Ldstr, eventId);
il.EmitCall(OpCodes.Callvirt, eventProcessor.GetType().GetMethod("ExecuteAction"), null);
il.Emit(OpCodes.Ret);
Type finished = tb.CreateType();
object helper = Activator.CreateInstance(finished);
MethodInfo eventHandler = finished.GetMethod(dynamicHandlerName);
Delegate d = Delegate.CreateDelegate(handlerType, helper, eventHandler);
eInfo.AddEventHandler(o, d);
}
}
}
}
}
}
}
#endregion
#region 设备数据读取处理(把设备变量的值绑定到对应组件的属性上)
#region 设备数据的读取方法
/// <summary>
/// 设备数据读取委托定义,用于处理跨线程访问控件属性的处理
/// </summary>
/// <param name="sender">事件源</param>
/// <param name="e">设备变量读取事件对象</param>
private delegate void FormReadDataDelegate(object sender, ReadEventArgs e);
/// <summary>
/// 设备数据的读取方法
/// </summary>
/// <param name="sender">事件源</param>
/// <param name="e">设备变量读取事件对象</param>
private void OnReadData(object sender, ReadEventArgs e)
{
try
{
//ICSharpCode.Core.LoggingService.Debug("开始刷新界面" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"));
Form[] runForms = this._runForms.Values.ToArray<Form>();
foreach (Form frm in runForms)
{
#region 过滤掉隐藏的窗口和没有动画的窗口
if (frm.Visible == false)
{
continue;
}
if (frm is FrmRunTemplate)
{
if ((frm as FrmRunTemplate).BHaveAction == false)
{
continue;
}
}
#endregion
if (frm.InvokeRequired)
{
FormReadDataDelegate d = new FormReadDataDelegate(ProcessReadData);
frm.BeginInvoke(d, new object[] { frm, e });
continue;
}
//ProcessReadData(frm , e);
}
//ICSharpCode.Core.LoggingService.Debug("结束刷新界面" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"));
}
catch (Exception ex)
{
//记录错误日志
ICSharpCode.Core.LoggingService.Error(ex.Message);// + "\r\n" + ex.StackTrace);
//MessageBox.Show(ex.Message);
}
}
#endregion
#region 把设备变量的值绑定到对应组件的属性上
/// <summary>
/// 把设备变量的值绑定到对应组件的属性上
/// </summary>
/// <param name="sender">事件源</param>
/// <param name="e">设备变量读取事件对象</param>
private void ProcessReadData(object sender, ReadEventArgs e)
{
//ICSharpCode.Core.LoggingService.Debug("设备开始绑定" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"));
try
{
Form frm = sender as Form;
//int n = frm.Controls.Count;
Control[] controls = GetAllControlsByForm(frm);
int n = controls.Length;
for (int i = 0; i < n; i++)
{
//Control o = frm.Controls[i];
Control o = controls[i];
string t = o.GetType().Name;
XmlNode tmpXActionNode = PublicConfig.Instance.ActionXmlDoc.SelectSingleNode(String.Format("Components/Component[@Name=\"{0}\"]", t));
if (tmpXActionNode != null)
{
XmlNodeList tmpXActionLst = tmpXActionNode.SelectNodes("Propertys/Property");
foreach (XmlNode node in tmpXActionLst)
{
System.Reflection.PropertyInfo propertyInfo = o.GetType().GetProperty(node.Attributes["Name"].Value); //获取动画属性
if (propertyInfo == null)
{
continue;
}
object varName = propertyInfo.GetValue(o, null);
if (varName != null)
{
if (node.Attributes["ControlPropertyName"] == null) continue;
System.Reflection.PropertyInfo controlProperty = o.GetType().GetProperty(node.Attributes["ControlPropertyName"].Value); //获取动画控制的属性
if (controlProperty != null)
{
try
{
if (e.Data.ContainsKey(varName.ToString())) //变量
{
//e.Data.
lock (o)
{
controlProperty.SetValue(o, this.ChangeType(e.Data[varName.ToString()], controlProperty.PropertyType.UnderlyingSystemType), null);
}
}
else
{
try
{
object d = ExpressValue(varName.ToString());
if (d != null && !(d is bool))
{
lock (o)
{
controlProperty.SetValue(o, this.ChangeType(d, controlProperty.PropertyType.UnderlyingSystemType), null);
}
}
}
catch (Exception ex)
{
ICSharpCode.Core.LoggingService.Error(varName.ToString() + ex.Message + "\r\n" + ex.StackTrace);
}
}
}
catch (Exception ex)
{
//ICSharpCode.Core.LoggingService.Error(varName.ToString() + "=" + e.Data[varName.ToString()].ToString());
ICSharpCode.Core.LoggingService.Error(varName.ToString() + ex.Message + "\r\n" + ex.StackTrace);
}
}
}
}
}
}
//ICSharpCode.Core.LoggingService.Debug("设备绑定已结束" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff"));
}
catch (Exception ex)
{
//ICSharpCode.Core.LoggingService.Error(varName.ToString() + ex.Message + "\r\n" + ex.StackTrace);
}
}
#endregion
#endregion
#region 设备数据读取异常处理
private delegate void FormExceptDataDelegate(object sender, Exception e);
private void OnExceptData(object sender, Exception ex)
{
//设备数据出错时的事件处理程序
}
#endregion
#region 把目标值转换为指定类型的对象
/// <summary>
/// 把目标值转换为指定类型的对象
/// </summary>
/// <param name="value">目标值</param>
/// <param name="type">要转换的目标类型</param>
/// <returns>返回转换指定类型后的对象</returns>
private object ChangeType(object value, Type type)
{
if (value == null && type.IsGenericType) return Activator.CreateInstance(type);
if (value == null) return null;
if (type == value.GetType()) return value;
if (type.IsEnum)
{
if (value is string)
return Enum.Parse(type, value as string);
else
return Enum.ToObject(type, Convert.ToInt32(value));
}
if (!type.IsInterface && type.IsGenericType)
{
Type innerType = type.GetGenericArguments()[0];
object innerValue = ChangeType(value, innerType);
return Activator.CreateInstance(type, new object[] { innerValue });
}
if (value is string && type == typeof(Guid)) return new Guid(value as string);
if (value is string && type == typeof(Version)) return new Version(value as string);
if (!(value is IConvertible)) return value;
return Convert.ChangeType(value, type);
}
#endregion
#region 仿真画面关闭业务处理
/// <summary>
/// 仿真画面关闭
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void frm_Disposed(object sender, EventArgs e)
{
Form frm = sender as Form;
if (this._runForms.ContainsKey(frm.Name))
{
this._runForms.Remove(frm.Name);
}
}
/// <summary>
/// 关闭所有画面
/// </summary>
public void CloseAllForms()
{
string[] frmNames = new string[this._runForms.Keys.Count];
this._runForms.Keys.CopyTo(frmNames, 0);
foreach (string frmName in frmNames)
{
if (this._runForms.ContainsKey(frmName))
{
if (!this._runForms[frmName].IsDisposed)
{
this._runForms[frmName].Close();
this._runForms.Remove(frmName);
}
}
}
}
#endregion
#endregion
#region 3、表达式与函数处理
//函数传到这个回调函数里
static object express_OnCallBack(string funcName, object[] param, ref bool isOk)
{
isOk = true;
string fun = funcName.ToUpper();
if (fun.Equals("SIN"))
{
return Math.Sin(Convert.ToDouble(param[0]));
}
else if (fun.Equals("COS"))
{
return Math.Cos(Convert.ToDouble(param[0]));
}
else if (fun.Equals("LOG10"))
{
return Math.Log10(Convert.ToDouble(param[0]));
}
else if (fun.Equals("EXP"))
{
return Math.Exp(Convert.ToDouble(param[0]));
}
else if (fun.Equals("ASIN"))
{
return Math.Asin(Convert.ToDouble(param[0]));
}
else if (fun.Equals("ACOS"))
{
return Math.Acos(Convert.ToDouble(param[0]));
}
else if (fun.Equals("ABS"))
{
return Math.Abs(Convert.ToDecimal(param[0]));
}
else if (fun.Equals("ATAN"))
{
return Math.Atan(Convert.ToDouble(param[0]));
}
else if (fun.Equals("CEILING"))
{
return Math.Ceiling(Convert.ToDouble(param[0]));
}
else if (fun.Equals("COSH"))
{
return Math.Cosh(Convert.ToDouble(param[0]));
}
else if (fun.Equals("FLOOR"))
{
return Math.Floor(Convert.ToDouble(param[0]));
}
else if (fun.Equals("SINH"))
{
return Math.Sinh(Convert.ToDouble(param[0]));
}
else if (fun.Equals("SQRT"))
{
return Math.Sqrt(Convert.ToDouble(param[0]));
}
else if (fun.Equals("TAN"))
{
return Math.Tan(Convert.ToDouble(param[0]));
}
else if (fun.Equals("TANH"))
{
return Math.Tanh(Convert.ToDouble(param[0]));
}
else if (fun.Equals("TRUNCATE"))
{
return Math.Truncate(Convert.ToDouble(param[0]));
}
isOk = false;
return 0;
}
//变量传到这个回调函数里
bool express_OnAccidenceAnalysis(ref Mesnac.Basic.Operand opd)
{
if (opd.Type == Mesnac.Basic.OperandType.STRING)
{
Dictionary<string, Mesnac.Equips.BaseEquip> allEquips = Mesnac.Equips.Factory.Instance.AllEquips;
foreach (string key in allEquips.Keys)
{
Dictionary<string, Mesnac.Equips.BaseInfo.Group> allGroups = allEquips[key].Group;
foreach (string key2 in allGroups.Keys)
{
//Dictionary<string, Mesnac.Equips.BaseInfo.Data> datas = allGroups[key2].Data;
Mesnac.Equips.BaseInfo.Data[] datas = new Equips.BaseInfo.Data[allGroups[key2].Data.Count];
allGroups[key2].Data.Values.CopyTo(datas, 0);
foreach (Mesnac.Equips.BaseInfo.Data data in datas)
{
if (data.KeyName.Equals(opd.Value.ToString()))
{
opd.Type = Mesnac.Basic.OperandType.NUMBER;
opd.Value = data.Value;
return true;
}
}
}
}
opd.Type = Mesnac.Basic.OperandType.NUMBER;
opd.Value = 0;
return false;
}
else
{
return true;
}
}
/// <summary>
/// 表达式求值
/// </summary>
/// <param name="sExpress"></param>
/// <returns></returns>
private object ExpressValue(string sExpress)
{
bool bok = express.Parse(sExpress);
if (bok)
{
bool ok = false;
object d = express.Evaluate(ref ok);
if (ok)
{
return d;
}
}
return null;
}
#endregion
public FrmRunTemplate getActiveFrmByName(string NodeName)
{
FrmRunTemplate frm = null;
if (this._runForms.ContainsKey(NodeName))
{
frm = this._runForms[NodeName] as FrmRunTemplate;
}
return frm;
}
/// <summary>
/// 获取主界面
/// </summary>
/// <returns></returns>
public void returnMainPage(string frmName)
{
string[] Formkey = this._runForms.Keys.ToArray<string>();
foreach (string key in Formkey)
{
if (this._runForms[key].Name != "Main")//这是主页面
{
if (this._runForms[key].Name.ToUpper() == "AUTO")//这是曲线页面
{
this._runForms[key].Hide();
}
else
{
this._runForms[key].Close();
}
}
}
}
}
}