Problem with using Roslyn in a MS Build Task
-
Friday, October 28, 2011 12:24 PM
I am experimenting with using Roslyn in an MS Build task (BeforeBuild Target) but have run into the following problem. When executing the attached code, the last line (accessing the references) throws an Exception: "Internal MSBuild Error: Cannot create in-proc node because operating environment is already owned by another." originating from here: "Microsoft.Build.dll!Microsoft.Build.Execution.BuildManager.ExecuteSubmission.AnonymousMethod__9(object context) + 0x46 bytes"
My setup is a test project which imports my custom task. For executing and debugging I just call MS Build through modified debug settings of my dev project with the appropriate file path to my test project.public class MyTask : Task { public override bool Execute() { string projectFileName = this.BuildEngine.ProjectFileOfTaskNode; var workspace = Workspace.LoadStandAloneProject(projectFileName); var solution = workspace.CurrentSolution; var project = solution.Projects.First(); var references = project.MetadataReferences;
...- Edited by havegot2beonline Friday, October 28, 2011 12:25 PM
All Replies
-
Friday, October 28, 2011 2:32 PMOwner
Hi,
Unfortunately, this isn't a scenario that we have tested much, so I don't have a simple workaround for you at the moment. The issue here is the the workspace you created will use msbuild to lazily evaluate properties such as MetadataReferences. However, msbuild is already in the middle of a build, and isn't happy with this re-entrancy. All I can think to of would be for you to move this logic into a separate AppDomain or process, so that you don't interfere with the state of the "outer" build.
Thanks for letting us know about this issue - can you file a bug on connect so that we can look into making this scenario easier?
Also - if you don't plan to ever modify the solution, you don't need to use the Workspace at all, you can just use Solution.LoadStandaloneProject too.
-- Kevin
-
Friday, October 28, 2011 6:07 PM
Thanks. I filed a bug on Connect here: https://connect.microsoft.com/VisualStudio/feedback/details/697724/problem-with-using-roslyn-in-a-ms-build-task#details
I've never worked with creating additional AppDomains before and I am running into a bit of trouble. I moved the code to a new project (so I get a separate assembly that I can load into AppDomain). When trying to load the Assembly in my code I get a FileNotFoundException. Looking into the Binding Logs didn't really get me any further. I also tried setting up the Bin-Path on the AppDomainSetup but it still didn't work. I can't even seem to load the origonal Assembly into a new AppDomain.
var appDomainSetup = new AppDomainSetup(); var appDomain = AppDomain.CreateDomain("Hallo", null, appDomainSetup);
var assembly = appDomain.Load(AssemblyName.GetAssemblyName(@"C:\...")); -
Friday, October 28, 2011 7:39 PMOwner
A simpler work-around for the time being may be to just avoid the Workspace API for this scenario. Since you already have access to MSBuild, you can create a Compilation object yourself (with a little effort):
public class MyTask : Task { public override bool Execute() { var projectFileName = this.BuildEngine.ProjectFileOfTaskNode; var project = ProjectCollection.GlobalProjectCollection.GetLoadedProjects(this.BuildEngine.ProjectFileOfTaskNode).Single(); var compilation = Compilation.Create(project.GetPropertyValue("AssemblyName"), syntaxTrees: project.GetItems("Compile").Select(c => SyntaxTree.ParseCompilationUnit(c.EvaluatedInclude)), references: project.GetItems("Reference").Select(r => MetadataReference.Create(r.EvaluatedInclude))); // Now work with compilation ... } }
This is basically what the Workspace is doing 'under the covers.'
Hope that helps
- Marked As Answer by havegot2beonline Saturday, October 29, 2011 9:19 AM
-
Saturday, October 29, 2011 9:20 AMThat seems to work, thanks.

