0

我之前将 CodeDOM CompilationUnits 导出到文件,然后将这些文件读回以使用 CSharpCodeProvider 编译它们。今天我重构了代码,以便将 CodeDOM 导出为字符串:

public static string compileToString(CodeCompileUnit cu){
        // Generate the code with the C# code provider.
        CSharpCodeProvider provider = new CSharpCodeProvider();

        using (StringWriter sw = new StringWriter())
        {
            IndentedTextWriter tw = new IndentedTextWriter(sw, "    ");

            // Generate source code using the code provider.
            provider.GenerateCodeFromCompileUnit(cu, tw,
                new CodeGeneratorOptions());

            tw.Close();

            return sw.ToString ();
        }   
    }

然后更改编译,使其使用 CompileFromSource:

public static Assembly BuildAssemblyFromString(string code){
        Microsoft.CSharp.CSharpCodeProvider provider = 
           new CSharpCodeProvider();
        ICodeCompiler compiler = provider.CreateCompiler();
        CompilerParameters compilerparams = new CompilerParameters();
        compilerparams.GenerateExecutable = false;
        compilerparams.GenerateInMemory = true;

        compilerparams.CompilerOptions = "/nowarn:162";
        string[] files = new string[]{"TemplateAesthetic.cs"};

        CompilerResults results = 
           compiler.CompileAssemblyFromSource(compilerparams, code);
        if (results.Errors.HasErrors)
        {
            StringBuilder errors = new StringBuilder("Compiler Errors :\r\n");
            foreach (CompilerError error in results.Errors )
            {
                errors.AppendFormat("Line {0},{1}\t: {2}\n", 
                       error.Line, error.Column, error.ErrorText);
                Debug.Log (error.ErrorText);
            }
        }
        else
        {
            return results.CompiledAssembly;
        }
        return null;
    }

感谢 Maarten 注意到:问题是我需要在编译过程中包含一个真实文件(TemplateAesthetic.cs),但这个编译是从一个字符串发生的。您可以使用 CompileAssemblyFromSource 以这种方式进行混合编译吗?

4

1 回答 1

1

初步答案:

据我所知,您的变量string[] files没有在任何地方使用。是否需要将它们添加到某处的编译器参数中?

更新:

您使用的方法实际上接受 aparams string[] sources这意味着您可以为该方法提供多个字符串。因此解决方案是将文件从磁盘读取到内存(字符串),并创建一个包含所有源的数组,并将该数组提供给该方法。

改变这个:

CompilerResults = compiler.CompileAssemblyFromSource(compilerparams, code);

对此:

var fileContents = files.Select(x => File.ReadAllText(x)).ToList();
fileContents.Add(code);
CompilerResults results = compiler.CompileAssemblyFromSource(
    compilerparams, 
    fileContents
);

抱歉,没时间测试。

于 2013-07-09T12:07:10.290 回答