我之前将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以这种方式进行混合编译吗?
答案 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
);
抱歉,没时间进行测试。