示例#1
0
        /// <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);
        }
示例#2
0
        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)));
            }
        }
示例#3
0
        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)));
            }
        }