如何在运行时从已编译的类中创建.NET exe文件程序集

时间:2014-08-18 08:58:30

标签: c# .net compilation .net-assembly

我需要在运行时创建可执行文件程序集。我的主要目标是从实际的Project(.dll)执行编译任务编译类型,而不使用字符串将需要编译的代码保存到输出exe文件。在代码开发/重构期间维护这些字符串将是一场噩梦。如下例所示,当我重构类CodeToCompile时,我还需要记住在RuntimeCompiler.Compile()方法中更改字符串codeToCompile:

using System;
using System.CodeDom.Compiler;

using Microsoft.CSharp;

namespace RuntimeCompiler
{
    public class Compiler
    {
        public void Compile()
        {
            string codeToCompile = 
                @"public class CodeToCompile
                {
                    public static void Main(string[] args)
                    {
                        Console.ReadLine();
                    }
                }";

            CSharpCodeProvider codeProvider = new CSharpCodeProvider();
            ICodeCompiler icc = codeProvider.CreateCompiler();
            CompilerParameters parameters = new CompilerParameters
                                                {
                                                    GenerateExecutable = true,
                                                    OutputAssembly = "Generated.exe"
                                                };

            CompilerResults results = icc.CompileAssemblyFromSource(parameters, codeToCompile);
        }

    }

    public class CodeToCompile
    {
        public static void Main(string[] args)
        {
            Console.ReadLine();
        }
    }
}

我想要实现的是使用需要编译的代码来更改字符串,以引用需要编译成.exe程序集的类型。

string codeToCompile = "..."; //CodeToCompile source code
CompilerResults results = icc.CompileAssemblyFromSource(parameters, codeToCompile);

CompilerResults results = icc.CompileAssemblyFromSource(parameters, typeof(CodeToCompile));

任何想法,最好的方法是什么?

我很容易找到有关如何使用System.CodeDom.Compiler命名空间从字符串动态编译C#代码的信息,如上所示。因此,任何获取运行时对象未编译代码作为字符串的方法都可以完成这项工作。我在这个方向上的研究没有给我解决方案,我强烈怀疑可以轻松地做到这一点。

我的第二个想法是使用机制将已编译的类型从正在运行的程序集“移动”到新创建的程序集,但遗憾的是我还没有找到任何解决方案来执行此任务。

1 个答案:

答案 0 :(得分:2)

  

...不使用字符串保存需要编译的代码以输出exe文件。在代码开发/重构期间维护这些字符串将是一场噩梦......

我的建议是调查.NET Globalization

  

全球化涉及设计和开发一个支持世界的应用程序,支持多种文化中用户的本地化界面和区域数据......处理字符和字符串是全球化的核心焦点,因为每个文化或地区可能使用不同的字符和字符集,并以不同的方式对它们进More...

CodeDom.Compiler的替代方案是.NET的Reflection Emit

  

... System.Reflection.Emit命名空间,允许编译器或工具在运行时发出元数据和Microsoft中间语言(MSIL),并可选择在磁盘上生成可移植可执行(PE)文件。脚本引擎和编译器是此命名空间的主要用户。 More...