// 准备脚本环境 int PrepareScript(string strProjectName, string strProjectLocate, out BiblioStatis objStatisParam, out MyFilterDocument filter, out string strError) { this.AssemblyMain = null; objStatisParam = null; filter = null; string strWarning = ""; /* string strInstanceDir = PathUtil.MergePath(strProjectLocate, "~bin_" + Guid.NewGuid().ToString()); PathUtil.CreateDirIfNeed(strInstanceDir); * */ string strMainCsDllName = Path.Combine(this.InstanceDir, "~biblio_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", // 2011/8/25 新增 Environment.CurrentDirectory + "\\digitalplatform.dp2.statis.dll", // Environment.CurrentDirectory + "\\Interop.SHDocVw.dll", Environment.CurrentDirectory + "\\dp2circulation.exe", }; // 创建Project中Script main.cs的Assembly // return: // -2 出错,但是已经提示过错误信息了。 // -1 出错 int nRet = ScriptManager.BuildAssembly( "BiblioStatisForm", 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.BiblioStatis"); if (entryClassType == null) { strError = strMainCsDllName + "中没有找到 dp2Circulation.BiblioStatis 派生类。"; goto ERROR1; } // new一个Statis派生对象 objStatisParam = (BiblioStatis)entryClassType.InvokeMember(null, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.CreateInstance, null, null, null); // 为Statis派生类设置参数 objStatisParam.BiblioStatisForm = this; objStatisParam.ProjectDir = strProjectLocate; objStatisParam.InstanceDir = this.InstanceDir; //// //////////////////////////// // 装载marfilter.fltx string strFilterFileName = Path.Combine(strProjectLocate, "marcfilter.fltx"); if (FileUtil.FileExist(strFilterFileName) == true) { filter = new MyFilterDocument(); filter.BiblioStatis = objStatisParam; filter.strOtherDef = entryClassType.FullName + " BiblioStatis = null;"; filter.strPreInitial = " MyFilterDocument doc = (MyFilterDocument)this.Document;\r\n"; filter.strPreInitial += " BiblioStatis = (" + entryClassType.FullName + ")doc.BiblioStatis;\r\n"; try { filter.Load(strFilterFileName); } catch (Exception ex) { strError = "文件 " + strFilterFileName + " 装载到MarcFilter时发生错误: " + ex.Message; goto ERROR1; } nRet = filter.BuildScriptFile(Path.Combine(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 = Path.Combine(strProjectLocate, "~marcfilter_" + Convert.ToString(AssemblyVersion++) + ".dll"); // 创建Project中Script的Assembly nRet = ScriptManager.BuildAssembly( "BiblioStatisForm", 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; }
/* 发生未捕获的界面线程异常: Type: System.NullReferenceException Message: 未将对象引用设置到对象的实例。 Stack: 在 dp2Circulation.BiblioStatisForm.RunScript(String strProjectName, String strProjectLocate, String strInitialParamString, String& strError, String& strWarning) 在 dp2Circulation.BiblioStatisForm.button_next_Click(Object sender, EventArgs e) 在 System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent) 在 System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) 在 System.Windows.Forms.Control.WndProc(Message& m) 在 System.Windows.Forms.ButtonBase.WndProc(Message& m) 在 System.Windows.Forms.Button.WndProc(Message& m) 在 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) * */ int RunScript(string strProjectName, string strProjectLocate, string strInitialParamString, out string strError, out string strWarning) { strError = ""; strWarning = ""; 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 = ""; strWarning = ""; this.DisposeBilbioStatisObject(); // this.objStatis = null; this.AssemblyMain = null; MyFilterDocument filter = null; // 2009/11/5 // 防止以前残留的打开的文件依然没有关闭 Global.ForceGarbageCollection(); nRet = PrepareScript(strProjectName, strProjectLocate, out this.objStatis, out filter, out strError); if (nRet == -1) goto ERROR1; // if (filter != null) this.AssemblyFilter = filter.Assembly; else this.AssemblyFilter = null; this.MarcFilter = filter; // Debug.Assert(objStatis != null, ""); objStatis.ProjectDir = strProjectLocate; objStatis.Console = this.Console; // 执行脚本的OnInitial() // 触发Script中OnInitial()代码 // OnInitial()和OnBegin的本质区别, 在于OnInitial()适合检查和设置面板参数 if (objStatis != null) { StatisEventArgs args = new StatisEventArgs(); args.ParamString = strInitialParamString; 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, out strWarning); if (nRet == -1) goto ERROR1; if (nRet == 1) goto END1; // 实际上 SkipAll 是要执行 OnEnd() 的,而 Error 才是不执行 OnEnd() END1: // 触发Script的OnEnd()代码 if (objStatis != null) { StatisEventArgs args = new StatisEventArgs(); objStatis.OnEnd(this, args); if (args.Continue == ContinueType.Error) { strError = args.ParamString; return -1; } } return 0; ERROR1: return -1; } catch (Exception ex) { strError = "脚本执行过程抛出异常: \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); } }