// 准备脚本环境 int PrepareScript(string strProjectName, string strProjectLocate, out ItemStatis objStatis, out AnotherFilterDocument filter, out string strError) { this.AssemblyMain = null; objStatis = null; filter = null; string strWarning = ""; string strMainCsDllName = PathUtil.MergePath(this.InstanceDir, "\\~item_statis_main_" + Convert.ToString(AssemblyVersion++) + ".dll"); // ++ string strLibPaths = "\"" + this.MainForm.DataDir + "\"" + "," + "\"" + strProjectLocate + "\""; string[] saAddRef = { // 2011/4/20 增加 "system.dll", "system.drawing.dll", "system.windows.forms.dll", "system.xml.dll", "System.Runtime.Serialization.dll", Environment.CurrentDirectory + "\\digitalplatform.marcdom.dll", Environment.CurrentDirectory + "\\digitalplatform.marckernel.dll", Environment.CurrentDirectory + "\\digitalplatform.marcquery.dll", //Environment.CurrentDirectory + "\\digitalplatform.rms.Client.dll", //Environment.CurrentDirectory + "\\digitalplatform.library.dll", // Environment.CurrentDirectory + "\\digitalplatform.statis.dll", Environment.CurrentDirectory + "\\digitalplatform.dll", Environment.CurrentDirectory + "\\digitalplatform.Text.dll", Environment.CurrentDirectory + "\\digitalplatform.IO.dll", Environment.CurrentDirectory + "\\digitalplatform.Xml.dll", Environment.CurrentDirectory + "\\digitalplatform.circulationclient.dll", Environment.CurrentDirectory + "\\digitalplatform.libraryclient.dll", Environment.CurrentDirectory + "\\digitalplatform.Script.dll", Environment.CurrentDirectory + "\\digitalplatform.dp2.statis.dll", // Environment.CurrentDirectory + "\\Interop.SHDocVw.dll", Environment.CurrentDirectory + "\\dp2circulation.exe", }; string strHostName = ""; if (this.DbType == "item") strHostName = "ItemStatisForm"; else if (this.DbType == "order") strHostName = "OrderStatisForm"; else if (this.DbType == "issue") strHostName = "IssueStatisForm"; else if (this.DbType == "comment") strHostName = "CommentStatisForm"; // 创建Project中Script main.cs的Assembly // return: // -2 出错,但是已经提示过错误信息了。 // -1 出错 int nRet = ScriptManager.BuildAssembly( strHostName, strProjectName, "main.cs", saAddRef, strLibPaths, strMainCsDllName, out strError, out strWarning); if (nRet == -2) goto ERROR1; if (nRet == -1) { if (strWarning == "") goto ERROR1; MessageBox.Show(this, strWarning); } this.AssemblyMain = Assembly.LoadFrom(strMainCsDllName); if (this.AssemblyMain == null) { strError = "LoadFrom " + strMainCsDllName + " fail"; goto ERROR1; } // 得到Assembly中Statis派生类Type Type entryClassType = ScriptManager.GetDerivedClassType( this.AssemblyMain, "dp2Circulation.ItemStatis"); if (entryClassType == null) { strError = strMainCsDllName + "中没有找到 dp2Circulation.ItemStatis 派生类。"; goto ERROR1; } // new一个Statis派生对象 objStatis = (ItemStatis)entryClassType.InvokeMember(null, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance, null, null, null); // 为Statis派生类设置参数 objStatis.ItemStatisForm = this; objStatis.ProjectDir = strProjectLocate; objStatis.InstanceDir = this.InstanceDir; //////////////////////////// // 装载marfilter.fltx string strFilterFileName = strProjectLocate + "\\marcfilter.fltx"; if (FileUtil.FileExist(strFilterFileName) == true) { filter = new AnotherFilterDocument(); filter.ItemStatis = objStatis; filter.strOtherDef = entryClassType.FullName + " ItemStatis = null;"; filter.strPreInitial = " AnotherFilterDocument doc = (AnotherFilterDocument)this.Document;\r\n"; filter.strPreInitial += " ItemStatis = (" + entryClassType.FullName + ")doc.ItemStatis;\r\n"; try { filter.Load(strFilterFileName); } catch (Exception ex) { strError = "文件 " + strFilterFileName + " 装载到MarcFilter时发生错误: " + ex.Message; goto ERROR1; } nRet = filter.BuildScriptFile(strProjectLocate + "\\marcfilter.fltx.cs", out strError); if (nRet == -1) goto ERROR1; // 一些必要的链接库 string[] saAddRef1 = { Environment.CurrentDirectory + "\\digitalplatform.marcdom.dll", Environment.CurrentDirectory + "\\digitalplatform.marckernel.dll", Environment.CurrentDirectory + "\\digitalplatform.marcquery.dll", //Environment.CurrentDirectory + "\\digitalplatform.rms.client.dll", //Environment.CurrentDirectory + "\\digitalplatform.library.dll", Environment.CurrentDirectory + "\\digitalplatform.dll", Environment.CurrentDirectory + "\\digitalplatform.Text.dll", Environment.CurrentDirectory + "\\digitalplatform.IO.dll", Environment.CurrentDirectory + "\\digitalplatform.Xml.dll", // Environment.CurrentDirectory + "\\Interop.SHDocVw.dll", Environment.CurrentDirectory + "\\dp2circulation.exe", strMainCsDllName}; // fltx文件里显式增补的链接库 string[] saAdditionalRef = filter.GetRefs(); // 合并的链接库 string[] saTotalFilterRef = new string[saAddRef1.Length + saAdditionalRef.Length]; Array.Copy(saAddRef1, saTotalFilterRef, saAddRef1.Length); Array.Copy(saAdditionalRef, 0, saTotalFilterRef, saAddRef1.Length, saAdditionalRef.Length); string strfilterCsDllName = strProjectLocate + "\\~marcfilter_" + Convert.ToString(AssemblyVersion++) + ".dll"; // 创建Project中Script的Assembly nRet = ScriptManager.BuildAssembly( strHostName, strProjectName, "marcfilter.fltx.cs", saTotalFilterRef, strLibPaths, strfilterCsDllName, out strError, out strWarning); if (nRet == -2) goto ERROR1; if (nRet == -1) { if (strWarning == "") { goto ERROR1; } MessageBox.Show(this, strWarning); } Assembly assemblyFilter = null; assemblyFilter = Assembly.LoadFrom(strfilterCsDllName); if (assemblyFilter == null) { strError = "LoadFrom " + strfilterCsDllName + "fail"; goto ERROR1; } filter.Assembly = assemblyFilter; } return 0; ERROR1: return -1; }
// TODO: OnEnd()有可能抛出异常,要能够截获和处理 int RunScript(string strProjectName, string strProjectLocate, out string strError) { EnableControls(false); stop.OnStop += new StopEventHandler(this.DoStop); stop.Initial("正在执行脚本 ..."); stop.BeginLoop(); this.Update(); this.MainForm.Update(); _dllPaths.Clear(); _dllPaths.Add(strProjectLocate); AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); try { int nRet = 0; strError = ""; // 2009/11/5 // 防止以前残留的打开的文件依然没有关闭 /* if (this.objStatis != null) { try { this.objStatis.FreeResources(); } catch { } } * */ this.objStatis = null; this.AssemblyMain = null; AnotherFilterDocument filter = null; // 2009/11/5 // 防止以前残留的打开的文件依然没有关闭 Global.ForceGarbageCollection(); nRet = PrepareScript(strProjectName, strProjectLocate, out objStatis, out filter, out strError); if (nRet == -1) goto ERROR1; // if (filter != null) this.AssemblyFilter = filter.Assembly; else this.AssemblyFilter = null; this.MarcFilter = filter; // objStatis.ProjectDir = strProjectLocate; objStatis.Console = this.Console; objStatis.LocationNames = this.textBox_locationNames.Text; // 执行脚本的OnInitial() // 触发Script中OnInitial()代码 // OnInitial()和OnBegin的本质区别, 在于OnInitial()适合检查和设置面板参数 if (objStatis != null) { StatisEventArgs args = new StatisEventArgs(); objStatis.OnInitial(this, args); if (args.Continue == ContinueType.SkipAll) goto END1; } // 触发Script中OnBegin()代码 // OnBegin()中仍然有修改MainForm面板的自由 if (objStatis != null) { StatisEventArgs args = new StatisEventArgs(); objStatis.OnBegin(this, args); if (args.Continue == ContinueType.SkipAll) goto END1; } // 循环 nRet = DoLoop(out strError); if (nRet == -1) goto ERROR1; if (nRet == 1) goto END1; // TODO: SkipAll如何执行? 是否连OnEnd也不执行了? END1: // 触发Script的OnEnd()代码 if (objStatis != null) { StatisEventArgs args = new StatisEventArgs(); objStatis.OnEnd(this, args); } return 0; ERROR1: return -1; } catch (Exception ex) { strError = "脚本 '" + strProjectName + "' 执行过程抛出异常: \r\n" + ExceptionUtil.GetDebugText(ex); return -1; } finally { if (objStatis != null) objStatis.FreeResources(); stop.EndLoop(); stop.OnStop -= new StopEventHandler(this.DoStop); stop.Initial(""); this.AssemblyMain = null; EnableControls(true); AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler(CurrentDomain_AssemblyResolve); } }