2016-09-09 86 views
2

我需要动态编译大项目源代码,输出类型可以是Windows应用程序或类库。 代码很好地执行,它可以使.dll或.exe文件,但问题是,当我试图制作.exe文件 - 它正在失去像项目图标资源。结果文件不包含汇编信息。动态编译项目丢失资源

有什么办法解决这个问题? (预期结果应该相同,Visual Studio 2015中的项目文件上的手动构建功能)。 谢谢!

var workspace = MSBuildWorkspace.Create(); 
//Locating project file that is WindowsApplication 
var project = workspace.OpenProjectAsync(@"C:\RoslynTestProjectExe\RoslynTestProjectExe.csproj").Result; 
var metadataReferences = project.MetadataReferences; 

// removing all references 
foreach (var reference in metadataReferences) 
{ 
    project = project.RemoveMetadataReference(reference); 
} 

//getting new path of dlls location and adding them to project 
var param = CreateParamString(); //my own function that returns list of references 
foreach (var par in param) 
{ 
    project = project.AddMetadataReference(MetadataReference.CreateFromFile(par)); 
} 

//compiling 
var projectCompilation = project.GetCompilationAsync().Result; 
using (var stream = new MemoryStream()) 
{ 
    var result = projectCompilation.Emit(stream); 
    if (result.Success) 
    { 
    /// Getting result 

    //writing exe file 
    using (var file = File.Create(Path.Combine(_buildPath, fileName))) 
    { 
     stream.Seek(0, SeekOrigin.Begin); 
     stream.CopyTo(file); 
    } 
    } 
} 
+0

如果你不介意做一些额外的工作,你可以在编译后自己手动嵌入它们。欲了解更多信息,请参阅:https://github.com/dotnet/roslyn/issues/7791 – JoshVarty

回答

2

我们从来没有真正设计过工作区API来包含所有需要发出的信息,特别是当你打电话给Emit时,你可以传递一个EmitOptions,其中包括资源信息。但是我们没有公开这些信息,因为这种情况没有得到很好的考虑。我们done some of the work in the past to enable this但最终从未合并过。您可能希望考虑提交错误,以便我们在某处正式提出请求。

那么你能做什么?我认为有几个选择。你可能考虑不使用Roslyn,而是修改项目文件并使用MSBuild API构建它。不幸的是,我不知道你最终想要在这里实现什么(如果你提到它,它会有所帮助),但不仅仅是构建项目所涉及的编译器调用。更改引用可能会改变其他内容。

当然,也可以自己更新MSBuildWorkspace来通过它。如果你要修改Roslyn代码,你会看到我们implement a series of interfaces named "ICscHostObject#" (where # is a number) and we get passed the information from MSBuild to that。看起来我们已经在命令行参数中存储了,所以您可能可以将它传递给我们的命令行解析器,并以这种方式获取数据。

+0

谢谢信息! – Bondjara