通用技术 使用 C# 动态编译并执行 HelloWorld 代码

SinDynasty · 2018年06月07日 · 2220 次阅读

首先我们在 E 盘下创建一个 HelloWorld.txt,并在其中写入以下代码并保存:

using System;

namespace HelloWorld
{
    public class HelloWorld
    {
        public static void Write()
        {
            Console.WriteLine("HelloWorld");
        }//void Write()

    }//class HelloWorld

}//namespace HelloWorld

然后我们创建一个控制台应用程序。在该程序中,我们首先需要读取该 HelloWorld.txt 中的内容。

FileStream HelloWorldStream = new FileStream(@"E:\HelloWorld.txt", FileMode.Open);
StreamReader HelloWorldReader = new StreamReader(HelloWorldStream);
string HelloWorldString = HelloWorldReader.ReadToEnd();

之后我们需要添加 System 的引用,以及在 NeGet 包管理器中添加 System.CodeDom 的引用。

然后创建一个 CSharpCodeProvider 对象,其将会为我们提供代码编译的功能。

CSharpCodeProvider CodeProvider = new CSharpCodeProvider();

之后我们还需要创建一个 CompilerParameters 对象,这是用于编译所需的参数,在其可以进行相关编译设置,例如设置在内存中编译生成程序集。

CompilerParameters Parameters = new CompilerParameters();
Parameters.GenerateInMemory = true;

然后调用 CSharpCodeProvider 中的 CompileAssemblyFromSource(CompilerParameters options, params string[] sources) 方法,并获得编译结果 CompilerResults

CompilerResults Results = CodeProvider.CompileAssemblyFromSource(Parameters, HelloWorldString);

检查编译是否成功,如果编译失败,则输出编译失败。

if (Results.Errors.HasErrors)
{
    Console.WriteLine("编译失败");
}

如果编译成功,则我们可以从 CompilerResults 中获取该程序集 HelloWorldAssembly。

Assembly HelloWorldAssembly = Results.CompiledAssembly;

然后从程序集 HelloWorldAssembly 中获取 class HelloWorld 的 Type

Type HelloWorldType = HelloWorldAssembly.DefinedTypes.First((Type) => { return Type.Name == "HelloWorld"; });

最后通过反射的方法,从 HelloWorldType 中获取 Write() 方法,并调用执行

MethodInfo WriteHelloWorldMethod = HelloWorldType.GetMethod("Write");
WriteHelloWorldMethod.Invoke(null, null);
共收到 0 条回复 时间 点赞
SinDynasty 重新开启了讨论 06月07日 12:11
SinDynasty 关闭了讨论 06月07日 12:11
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册