从字符串以编程方式编译时包含C#文件

时间:2013-07-09 11:46:55

标签: c# compilation codedom

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

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以这种方式进行混合编译吗?

1 个答案:

答案 0 :(得分:1)

初步答复:

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

更新

您使用的方法实际上接受params 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
);

抱歉,没时间进行测试。