/// <summary> /// 编译脚本 /// </summary> /// <returns>编译是否成功</returns> public bool Compile() { if (bolClosedFlag) { return(false); } intScriptVersion++; bolDebuged = false; myScriptMethods.Clear(); myAssembly = null; bolScriptModified = false; // 生成编译用的完整的VB源代码 string ModuleName = "mdlXVBAScriptEngine"; string nsName = "NameSpaceXVBAScriptEngien"; System.Text.StringBuilder mySource = new System.Text.StringBuilder(); mySource.Append("Option Strict Off"); foreach (string import in this.mySourceImports) { mySource.Append("\r\nImports " + import); } mySource.Append("\r\nNamespace " + nsName); mySource.Append("\r\nModule " + ModuleName); mySource.Append("\r\n"); mySource.Append("sub Cal() \r\ntry \r\n"); string datTmp = mySource.ToString(); startCodeLineCount = datTmp.Split('\r').Length; mySource.Append(this.strScriptText); mySource.Append("\r\nCatch ex As Exception \r\nh.show(ex.tostring) \r\nEnd Try \r\nend sub"); mySource.Append("\r\nEnd Module"); mySource.Append("\r\nEnd Namespace"); string strRuntimeSource = mySource.ToString(); // 检查程序集缓存区 myAssembly = (System.Reflection.Assembly)myAssemblies[strRuntimeSource]; if (myAssembly == null) { // 设置编译参数 this.myCompilerParameters.GenerateExecutable = false; this.myCompilerParameters.GenerateInMemory = true; this.myCompilerParameters.IncludeDebugInformation = true; if (this.myVBCompilerImports.Count > 0) { // 添加 imports 指令 System.Text.StringBuilder opt = new System.Text.StringBuilder(); foreach (string import in this.myVBCompilerImports) { if (opt.Length > 0) { opt.Append(","); } opt.Append(import.Trim()); } opt.Insert(0, " /imports:"); for (int iCount = 0; iCount < this.myVBCompilerImports.Count; iCount++) { this.myCompilerParameters.CompilerOptions = opt.ToString(); } }//if if (this.bolOutputDebug) { // 输出调试信息 System.Diagnostics.Debug.WriteLine(" Compile VBA.NET script \r\n" + strRuntimeSource); foreach (string dll in this.myCompilerParameters.ReferencedAssemblies) { System.Diagnostics.Debug.WriteLine("Reference:" + dll); } } // 对VB.NET代码进行编译 Microsoft.VisualBasic.VBCodeProvider provider = new Microsoft.VisualBasic.VBCodeProvider(); #if DOTNET11 // 这段代码用于微软.NET1.1 ICodeCompiler compiler = provider.CreateCompiler(); CompilerResults result = compiler.CompileAssemblyFromSource( this.myCompilerParameters, strRuntimeSource); #else // 这段代码用于微软.NET2.0或更高版本 CompilerResults result = provider.CompileAssemblyFromSource( this.myCompilerParameters, strRuntimeSource); #endif // 获得编译器控制台输出文本 System.Text.StringBuilder myOutput = new System.Text.StringBuilder(); foreach (string line in result.Output) { myOutput.Append("\r\n" + line); } this.strCompilerOutput = myOutput.ToString(); if (this.bolOutputDebug) { // 输出编译结果 if (this.strCompilerOutput.Length > 0) { //System.Diagnostics.Debug.WriteLine("VBAScript Compile result" + strCompilerOutput); ////////////////////// //string strErrorMsg = "检测出 " + result.Errors.Count.ToString() + " 个错误:"; string strErrorMsg = string.Empty; int count = 0; for (int x = 0; x < result.Errors.Count; x++) { if (result.Errors[x].IsWarning) { continue; } strErrorMsg = strErrorMsg + Environment.NewLine + "第 " + (result.Errors[x].Line - (startCodeLineCount - 1)).ToString() + " 行: " + result.Errors[x].ErrorText; count++; } strErrorMsg = "检测出 " + count.ToString() + " 个错误:" + strErrorMsg; strCompilerOutput = strErrorMsg; /////////////////////// } } provider.Dispose(); if (result.Errors.HasErrors == false) { // 若没有发生编译错误则获得编译所得的程序集 this.myAssembly = result.CompiledAssembly; } if (myAssembly != null) { // 将程序集缓存到程序集缓存区中 myAssemblies[strRuntimeSource] = myAssembly; } } if (this.myAssembly != null) { // 检索脚本中定义的类型 Type ModuleType = myAssembly.GetType(nsName + "." + ModuleName); if (ModuleType != null) { System.Reflection.MethodInfo[] ms = ModuleType.GetMethods( System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static); foreach (System.Reflection.MethodInfo m in ms) { // 遍历类型中所有的静态方法 // 对每个方法创建一个脚本方法信息对象并添加到脚本方法列表中。 ScriptMethodInfo info = new ScriptMethodInfo(); info.MethodName = m.Name; info.MethodObject = m; info.ModuleName = ModuleType.Name; info.ReturnType = m.ReturnType; this.myScriptMethods.Add(info); if (this.bolOutputDebug) { // 输出调试信息 System.Diagnostics.Debug.WriteLine("Get vbs method \"" + m.Name + "\""); } } //foreach bolDebuged = true; } //if } //if return(bolDebuged); }
public void CompileAndExecuteFile(string[] files, string[] args, IScriptManagerCallback callback, string[] filesToEmbed) { const int numITemplateFiles = 5; string[] extraFiles = new string[files.Length + numITemplateFiles]; for (int i = 0; i < files.Length; i++) { extraFiles[i] = files[i]; } StreamReader sr = null; StreamWriter sw = null; try { string tempFile = Path.Combine(Path.GetTempPath(), "Folder.cs"); sr = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(@"SlyceScripter.Config.Folder.cs")); sw = File.CreateText(tempFile); sw.Write(sr.ReadToEnd()); sr.Close(); sw.Flush(); sw.Close(); extraFiles[files.Length] = tempFile; tempFile = Path.Combine(Path.GetTempPath(), "Option.cs"); sr = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(@"SlyceScripter.Config.Option.cs")); sw = File.CreateText(tempFile); sw.Write(sr.ReadToEnd()); sr.Close(); sw.Flush(); sw.Close(); extraFiles[files.Length + 1] = tempFile; tempFile = Path.Combine(Path.GetTempPath(), "Output.cs"); sr = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(@"SlyceScripter.Config.Output.cs")); sw = File.CreateText(tempFile); sw.Write(sr.ReadToEnd()); sr.Close(); sw.Flush(); sw.Close(); extraFiles[files.Length + 2] = tempFile; tempFile = Path.Combine(Path.GetTempPath(), "Project.cs"); sr = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(@"SlyceScripter.Config.Project.cs")); sw = File.CreateText(tempFile); sw.Write(sr.ReadToEnd()); sr.Close(); sw.Flush(); sw.Close(); extraFiles[files.Length + 3] = tempFile; tempFile = Path.Combine(Path.GetTempPath(), "Script.cs"); sr = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream(@"SlyceScripter.Config.Script.cs")); sw = File.CreateText(tempFile); sw.Write(sr.ReadToEnd()); sr.Close(); sw.Flush(); sw.Close(); extraFiles[files.Length + 4] = tempFile; } catch { if (sr != null) { sr.Close(); } if (sw != null) { sw.Close(); } } files = extraFiles; string outputFileName = ""; string nrfFileName = ""; foreach (string arg in args) { if (arg.IndexOf("outputFileName=") >= 0) { outputFileName = arg.Substring("outputFileName=".Length); } else if (arg.IndexOf("nrfFileName=") >= 0) { nrfFileName = arg.Substring("nrfFileName=".Length); } } if (outputFileName.Length == 0) { throw new ApplicationException("Output file type is missing."); } bool isExe = (outputFileName.IndexOf(".exe") > 0); //Currently only csharp scripting is supported CodeDomProvider provider; string extension = Path.GetExtension(files[0]); switch (extension) { case ".cs": case ".ncs": provider = new Microsoft.CSharp.CSharpCodeProvider(); break; case ".vb": case ".nvb": provider = new Microsoft.VisualBasic.VBCodeProvider(); break; case ".njs": case ".js": provider = (CodeDomProvider)Activator.CreateInstance("Microsoft.JScript", "Microsoft.JScript.JScriptCodeProvider").Unwrap(); break; default: throw new UnsupportedLanguageExecption(extension); } var compiler = provider.CreateCompiler(); var compilerparams = new CompilerParameters { GenerateInMemory = false, GenerateExecutable = isExe, OutputAssembly = outputFileName }; // Embed resource file string optionPath = Path.Combine(Path.GetTempPath(), "options.xml"); string allCompilerOptions = @"/res:" + optionPath + ","; //compilerparams.CompilerOptions = @"/res:"+ optionPath; // Embed extra files, but not the first one which is the .cs file to compile, and // not the files which implement the ITemplate functions for (int i = 1; i < filesToEmbed.Length; i++) { string embeddedFilePath = Path.Combine(Controller.TempPath, filesToEmbed[i]); if (!File.Exists(embeddedFilePath) && embeddedFilePath.Length > 0) { System.Windows.Forms.MessageBox.Show(Controller.Instance.MainForm, "File not found: " + embeddedFilePath + ". Compile aborted.", "Missing file", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Error); return; } string resFilePath = Path.Combine(Path.GetDirectoryName(embeddedFilePath), Path.GetFileNameWithoutExtension(embeddedFilePath) + ".xml"); string resFileNameOnly = Path.GetFileNameWithoutExtension(embeddedFilePath) + ".xml"; CreateResourceFile(embeddedFilePath, resFilePath); File.Copy(resFilePath, resFileNameOnly, true); allCompilerOptions += resFilePath + ","; //allCompilerOptions += @"/res:"+ resFileNameOnly +","; //allCompilerOptions += @"/res:"+ optionPath +","; } // Remove the trailing comma compilerparams.CompilerOptions = allCompilerOptions.Substring(0, allCompilerOptions.Length - 1); //Add assembly references from nscript.nrf or <file>.nrf if (File.Exists(nrfFileName)) { AddReferencesFromFile(compilerparams, nrfFileName); } else { //Use nscript.nrf string nrfFile = Path.Combine(Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath), "nscript.nrf"); if (File.Exists(nrfFile)) { AddReferencesFromFile(compilerparams, nrfFile); } } CompilerResults results = compiler.CompileAssemblyFromFileBatch(compilerparams, files); if (results.Errors.HasErrors) { System.Collections.ArrayList templist = new System.Collections.ArrayList(); foreach (System.CodeDom.Compiler.CompilerError error in results.Errors) { templist.Add(new CompilerError(error)); } callback.OnCompilerError((CompilerError[])templist.ToArray(typeof(CompilerError))); } }