C#动态编译、执行代码
在开始之前,先熟悉几个类及部分属性、方法:CSharpCodeProvider、ICodeCompiler、CompilerParameters、CompilerResults、Assembly。
一、CSharpCodeProvider
提供对C#代码生成器和代码编译器的实例的访问。如果要动态生成VB代码,可以使用VBCodeProvider。
CreateCompiler():获取编译器的实例。
二、ICodeCompiler
定义用于调用源代码编译的接口或使用指定编译器的CodeDOM树。每种编译方法都接受指示编译器的CompilerParameters对象,并返回指示编译结果的CompilerResults对象。
这个接口可以不实现,直接用CSharpCodeProvider类的实例的CompilerAssemblyFromSource()方法编译程序
CompilerAssemblyFromSource(CompilerParameters option, string
source):使用指定的编译器,从包含源代码的字符串设置编译程序集。
三、CompilerParameters
表示用于调用编译器的参数。
ReferencedAssemblies:获取当前项目所引用的程序集。Add方法为程序集添加引用。
GenerateExecutable:获取或设置一个值,该值指示是否生成可执行文件。若此属性为false,则生成DLL,默认是false。
GenerateInMemory:获取或设置一个值,该值指示是否在内存中生成输出。
四、CompilerResults
表示从编译器返回的编译结果。
CompiledAssembly:获取或设置以编译的程序集,Assembly类型。
五、Assembly
就是程序集了(不知道如何描述了)。
大致了解了以上知识之后,就可以使用C#动态的编译并执行代码了,一下是一段示例程序:
using System; using System.Reflection; using System.Globalization; using Microsoft.CSharp; using System.CodeDom; using System.CodeDom.Compiler; using System.Text; namespace ConsoleApplication1 { public class Program { static void Main(string[] args) { //1.CSharpCodePrivoder CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider(); //2.ICodeComplier ICodeCompiler objICodeCompiler = objCSharpCodePrivoder.CreateCompiler(); //3.CompilerParameters CompilerParameters objCompilerParameters = new CompilerParameters(); objCompilerParameters.ReferencedAssemblies.Add("System.dll"); objCompilerParameters.GenerateExecutable =false; objCompilerParameters.GenerateInMemory = true; //4.CompilerResults CompilerResults cr = objICodeCompiler.CompileAssemblyFromSource(objCompilerParameters, GenerateCode()); if (cr.Errors.HasErrors) { Console.WriteLine("编译错误:"); foreach (CompilerError err in cr.Errors) { Console.WriteLine(err.ErrorText); } } else { // 通过反射,调用HelloWorld的实例 Assembly objAssembly = cr.CompiledAssembly; object objHelloWorld = objAssembly.CreateInstance("DynamicCodeGenerate.HelloWorld"); MethodInfo objMI = objHelloWorld.GetType().GetMethod("OutPut"); Console.WriteLine(objMI.Invoke(objHelloWorld, null)); } Console.ReadLine(); } static string GenerateCode() { StringBuilder sb = new StringBuilder(); sb.Append("using System;"); sb.Append(Environment.NewLine); sb.Append("namespace DynamicCodeGenerate"); sb.Append(Environment.NewLine); sb.Append("{"); sb.Append(Environment.NewLine); sb.Append(" public class HelloWorld"); sb.Append(Environment.NewLine); sb.Append(" {"); sb.Append(Environment.NewLine); sb.Append(" public string OutPut()"); sb.Append(Environment.NewLine); sb.Append(" {"); sb.Append(Environment.NewLine); sb.Append(" return /"Hello world!/";"); sb.Append(Environment.NewLine); sb.Append(" }"); sb.Append(Environment.NewLine); sb.Append(" }"); sb.Append(Environment.NewLine); sb.Append("}"); string code = sb.ToString(); Console.WriteLine(code); Console.WriteLine(); return code; } } } --------------------------------------------------------------------------------------------- Microsoft.CSharp.CSharpCodeProvider provider = new Microsoft.CSharp.CSharpCodeProvider(); System.CodeDom.Compiler.ICodeCompiler comp = provider.CreateCompiler(); System.CodeDom.Compiler.CompilerParameters cp = new System.CodeDom.Compiler.CompilerParameters(); cp.ReferencedAssemblies.Add("system.dll") ; cp.ReferencedAssemblies.Add("system.data.dll") ; cp.ReferencedAssemblies.Add("system.xml.dll") ; cp.GenerateExecutable = false ; cp.GenerateInMemory = true ; string code = @"using System; using System.Data; using System.Xml; public class Judgement { public object GetJude() { return (" + expression + @"); } }" ; System.CodeDom.Compiler.CompilerResults cr = comp.CompileAssemblyFromSource(cp,code); System.Diagnostics.Debug.Write(code); if(cr.Errors.HasErrors) { System.Text.StringBuilder errorMsg = new System.Text.StringBuilder(); foreach(System.CodeDom.Compiler.CompilerError err in cr.Errors) { errorMsg.Append(err.ErrorText ); } System.Diagnostics.Debug.WriteLine(errorMsg.ToString()); throw new System.Exception("编译错误: " + errorMsg.ToString()); //return false; } else { System.Reflection.Assembly tmp = cr.CompiledAssembly; object _Compiled = tmp.CreateInstance("Judgement"); System.Reflection.MethodInfo mi = _Compiled.GetType().GetMethod("GetJude"); return mi.Invoke(_Compiled,null); } /*------------------------------------*/

浙公网安备 33010602011771号