【问题标题】:C# Runtime Compilation with CSharpCodeProvider使用 CSharpCodeProvider 进行 C# 运行时编译
【发布时间】:2016-02-11 23:36:59
【问题描述】:

我已成功使用本教程:http://www.codeproject.com/Tips/715891/Compiling-Csharp-Code-at-Runtime 建立了一个用于运行时编译和执行 C# 代码的框架。以下是我目前拥有的代码:

public static class CodeCompiler {

public static object InterpretString(string executable) {
    string compilation_string = 
    @"
    static class RuntimeCompilationCode { 
        public static void Main() {}  
        public static object Custom() {
            /* CODE HERE */
        }
    }";

    compilation_string = compilation_string.Replace("/* CODE HERE */", executable);

    CSharpCodeProvider provider = new CSharpCodeProvider();
    CompilerParameters compiler_parameters = new CompilerParameters();

    // True - memory generation, false - external file generation
    compiler_parameters.GenerateInMemory = true;

    // True - exe file generation, false - dll file generation
    compiler_parameters.GenerateExecutable = true;

    // Compile
    CompilerResults results = provider.CompileAssemblyFromSource(compiler_parameters, compilation_string);

    // Check errors
    if (results.Errors.HasErrors) {
        StringBuilder builder = new StringBuilder();
        foreach (CompilerError error in results.Errors) {
            builder.AppendLine(String.Format("Error ({0}): {1}", error.ErrorNumber, error.ErrorText));
        }
        throw new InvalidOperationException(builder.ToString());
    }

    // Execute
    Assembly assembly = results.CompiledAssembly;
    Type program = assembly.GetType("RuntimeCompilationCode");
    MethodInfo execute = program.GetMethod("Custom");
    return execute.Invoke(null, null);
}

}

我可以将字符串形式的语句(例如"return 2;")传递给InterpretString(),它将作为Custom()函数的一部分进行编译和执行。但是我想知道是否可以使用相同的方法来执行我原始文件中的方法。例如,假设CodeCompiler 类有另一个方法returnsTwo(),它返回整数2。有没有办法通过将"CodeCompiler.returnsTwo();" 或类似的字符串传递给InterpretString() 来调用这样的方法?

【问题讨论】:

    标签: c# csharpcodeprovider


    【解决方案1】:

    只要函数是静态函数,这应该没有问题,只要在编译时添加适当的引用即可。我在几个项目中都做了这么短的事情。

    如果 CodeCompiler 在您当前的可执行文件中,您必须以这种方式包含引用:

    string exePath = Assembly.GetExecutingAssembly().Location;
    string exeDir = Path.GetDirectoryName(exePath);
    
    AssemblyName[] assemRefs = Assembly.GetExecutingAssembly().GetReferencedAssemblies();
    List<string> references = new List<string>();
    
    foreach (AssemblyName assemblyName in assemRefs)
        references.Add(assemblyName.Name + ".dll");
    
    for (int i = 0; i < references.Count; i++)
    {
        string localName = Path.Combine(exeDir, references[i]);
    
        if (File.Exists(localName))
            references[i] = localName;
    }
    
    references.Add(exePath);
    
    CompilerParameters compiler_parameters = new CompilerParameters(references.ToArray())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多