如何用C#动态编译、执行代码

在开始之前,先熟悉几个类及部分属性、方法:CSharpCodeProviderICodeCompilerCompilerParametersCompilerResultsAssembly

  一、CSharpCodeProvider
    提供对C#代码生成器和代码编译器的实例的访问。如果要动态生成VB代码,可以使用VBCodeProvider

    CreateCompiler():获取编译器的实例。

  二、ICodeCompiler
    定义用于调用源代码编译的接口或使用指定编译器的CodeDOM树。每种编译方法都接受指示编译器的CompilerParameters对象,并返回指示编译结果的CompilerResults对象。

    CompilerAssemblyFromSource(CompilerParameters option, string source):使用指定的编译器,从包含源代码的字符串设置编译程序集。

  三、CompilerParameters
    表示用于调用编译器的参数。

    ReferencedAssemblies:获取当前项目所引用的程序集。Add方法为程序集添加引用。
    GenerateExecutable:获取或设置一个值,该值指示是否生成可执行文件。若此属性为false,则生成DLL,默认是false。
    GenerateInMemory:获取或设置一个值,该值指示是否在内存中生成输出。

  四、CompilerResults
    表示从编译器返回的编译结果。

    CompiledAssembly:获取或设置以编译的程序集,Assembly类型。

  五、Assembly
    就是程序集了(不知道如何描述了)。

  大致了解了以上知识之后,就可以使用C#动态的编译并执行代码了,一下是一段示例程序:

 1 using System; 
 2 using System.Reflection; 
 3 using System.Globalization; 
 4 using Microsoft.CSharp;
 5 using System.CodeDom; 
 6 using System.CodeDom.Compiler;
 7 using System.Text; 
 8 
 9 namespace ConsoleApplication1 
10 {
11     public class Program
12     {
13         static void Main(string[] args)
14         {
15             // 1.CSharpCodePrivoder
16             CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider();
17 
18             // 2.ICodeComplier
19             ICodeCompiler objICodeCompiler = objCSharpCodePrivoder.CreateCompiler();
20 
21             // 3.CompilerParameters
22             CompilerParameters objCompilerParameters = new CompilerParameters();
23             objCompilerParameters.ReferencedAssemblies.Add("System.dll");
24             objCompilerParameters.GenerateExecutable = false;
25             objCompilerParameters.GenerateInMemory = true;
26 
27             // 4.CompilerResults
28             CompilerResults cr = objICodeCompiler.CompileAssemblyFromSource(objCompilerParameters, GenerateCode());
29 
30             if (cr.Errors.HasErrors)
31             {
32                 Console.WriteLine("编译错误:");
33                 foreach (CompilerError err in cr.Errors)
34                 {
35                     Console.WriteLine(err.ErrorText);
36                 }
37             }
38             else
39             {
40                 // 通过反射,调用HelloWorld的实例
41                 Assembly objAssembly = cr.CompiledAssembly;
42                 object objHelloWorld = objAssembly.CreateInstance("DynamicCodeGenerate.HelloWorld");
43                 MethodInfo objMI = objHelloWorld.GetType().GetMethod("OutPut");
44 
45                 Console.WriteLine(objMI.Invoke(objHelloWorld, null));
46             }
47 
48             Console.ReadLine();
49         }
50 
51         static string GenerateCode()
52         {
53             StringBuilder sb = new StringBuilder();
54             sb.Append("using System;");
55             sb.Append(Environment.NewLine);
56             sb.Append("namespace DynamicCodeGenerate");
57             sb.Append(Environment.NewLine);
58             sb.Append("{");
59             sb.Append(Environment.NewLine);
60             sb.Append("    public class HelloWorld");
61             sb.Append(Environment.NewLine);
62             sb.Append("    {");
63             sb.Append(Environment.NewLine);
64             sb.Append("        public string OutPut()");
65             sb.Append(Environment.NewLine);
66             sb.Append("        {");
67             sb.Append(Environment.NewLine);
68             sb.Append("             return "Hello world!";");
69             sb.Append(Environment.NewLine);
70             sb.Append("        }");
71             sb.Append(Environment.NewLine);
72             sb.Append("    }");
73             sb.Append(Environment.NewLine);
74             sb.Append("}");
75 
76             string code = sb.ToString();
77             Console.WriteLine(code);
78             Console.WriteLine();
79 
80             return code;
81         }
82     }
83 }
原文地址:https://www.cnblogs.com/weifeng123/p/9753881.html