繁体   English   中英

使用CSharpCodeProvider进行C#运行时编译

[英]C# Runtime Compilation with CSharpCodeProvider

使用本教程,我已经取得了成功: 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类具有另一个返回整数2的方法returnsTwo() 。是否可以通过传递"CodeCompiler.returnsTwo();"来调用这种方法? 还是类似于InterpretString()字符串?

只要该函数是静态函数,这就不成问题,只要您向编译添加适当的引用即可。 我在几个项目上都做不到这件事。

如果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())

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM