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
{
///
/// 运行引擎类
///
public class RunEngine
{
#region 字段定义
private string _projectPath = String.Empty; //组态工程路径
private AccidenceAnalyzer express; //表达式解析器
private TreeView _tree = null; //解析组态工程后的工程树
private Dictionary _runForms = new Dictionary(); //运行的组态画面列表
private bool _isLoad = false; //是否已载入工程
private bool _isControlPruview = false; //是否启用权限控制
#endregion
#region 属性定义
///
/// 是否启用权限控制
///
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 运行引擎初始化
///
/// 运行引擎初始化
///
/// 工程路径
/// 是否自动执行自启动Action
public bool Init(string projectPath, bool isAutoRun, bool isControlPurview)
{
LoggingService.Debug("运行引擎初始化...");
this._projectPath = projectPath;
this._isControlPruview = isControlPurview;
return this.Reload(isAutoRun);
}
#endregion
#region 重新加载工程
///
/// 重新加载工程
///
/// 是否自动执行自启动Action
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 获取工程数据源文件
///
/// 获取工程数据源文件
///
///
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 重置工程数据源工厂,从文件读取数据
///
/// 重置工程数据源工厂,从文件读取数据
///
private void ResetProjectDataSourceFactory(params CallBackDelegate[] callBack)
{
string fileName = this.GetProjectDataSourceFile();
if (!String.IsNullOrEmpty(fileName))
{
DataSourceFactory.Instance.RefreshDataFromFile(fileName, callBack);
}
}
#endregion
#endregion
#region 2、画面仿真主业务相关方法
#region 画面仿真方法
///
/// 画面仿真方法
///
/// 要仿真的画面节点
/// 画面显示方式:Document、Form、Dialog
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 dic = XmlHandler.ParseFormXml(fileName);
Host.HostSurfaceManager hsManager = Mesnac.Core.Service.MesnacServiceManager.Instance.HostSurfaceManager;
Host.HostControl hostControl = hsManager.LoadNewHost(fileName);
List 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画面仿真
///
/// 画面仿真方法
///
/// 要仿真的画面节点
/// 画面显示方式:Document、Form、Dialog
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 dic = XmlHandler.ParseFormXml(fileName);
Host.HostSurfaceManager hsManager = Mesnac.Core.Service.MesnacServiceManager.Instance.HostSurfaceManager;
Host.HostControl hostControl = hsManager.LoadNewHost(fileName);
List 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 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 仿真方法注释
/*
///
/// 仿真方法
///
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 dic = XmlHandler.ParseFormXml(fileName);
Host.HostSurfaceManager hsManager = Mesnac.Core.Service.MesnacServiceManager.Instance.HostSurfaceManager;
Host.HostControl hostControl = hsManager.LoadNewHost(fileName);
List 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 递归获取窗体下的所有控件
///
/// 获取窗体内的所有控件,包括子级
///
///
///
private static Control[] GetAllControlsByForm(Form frm)
{
List controlList = new List();
GetAllControlsByParentControl(controlList, frm);
return controlList.ToArray();
}
///
/// 递归获取控件下的子级控件
///
///
///
private static void GetAllControlsByParentControl(List controlList, Control parentControl)
{
foreach (Control c in parentControl.Controls)
{
controlList.Add(c);
GetAllControlsByParentControl(controlList, c);
}
}
#endregion
#region 递归获取当前控件的父级控件
///
/// 递归获取当前控件的父级控件
///
/// xml窗体文件中的ObjectDescriptor集合
/// 顶层控件,一般是Form
/// 当前控件
/// 返回当前控件的父级控件
private static Control FindParentControl(Dictionary 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 复制组件属性
///
/// 复制组件属性
///
/// xml窗体文件中的ObjectDescriptor集合
/// 源组件
/// 目标组件
/// 返回复制完属性后的目标组件
private static Component CopyComponent(Dictionary 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 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 获取组件名称
///
/// 获取组件名称
///
/// 要获取名称的组件
/// 返回组件名称
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 为组件绑定事件
///
/// 绑定事件
///
/// 要绑定事件的组件对象
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 tmpActionList = actionList as List;
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 设备数据的读取方法
///
/// 设备数据读取委托定义,用于处理跨线程访问控件属性的处理
///
/// 事件源
/// 设备变量读取事件对象
private delegate void FormReadDataDelegate(object sender, ReadEventArgs e);
///
/// 设备数据的读取方法
///
/// 事件源
/// 设备变量读取事件对象
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