Using BuildManager to build project causes a nuget package DLL to get locked

625 Views Asked by At

I am executing the following code:

public static BuildResult Compile(string projectFilePath)
{
    Nuget.NugetRestore(projectFilePath);
    ProjectCollection pc = new ProjectCollection();
    Dictionary<string, string> globalProperty = new Dictionary<string, string>();
    globalProperty.Add("nodeReuse","false");
    BuildParameters bp = new BuildParameters(pc);
    BuildRequestData buildRequest = new BuildRequestData(
        projectFilePath, globalProperty, "4.0", new string[] { "Clean", "Build" }, null);
    BuildResult buildResult = BuildManager.DefaultBuildManager.Build(bp, buildRequest);
    BuildManager.DefaultBuildManager.Dispose();
    return buildResult;
}

However when the build task is completed, when I attempt to delete the folder - I am prevented from doing so, because my application has loaded a DLL into memory from the solutions package folder.

Specifically Microsoft.Bcl.Build.Tasks.dll

Because this one file ends up getting 'in use' in my application, my application is not able to delete the temp directory until the application closes.
Chicken and the Egg - I don't want to close the application until the folder is gone, and I cannot delete the folder until the application closes.

Anyone got any solutions that are known to work?
Eg:
I know that once a DLL is loaded in the application, it is permanent and cannot be traditionally released.
However- I have heard in the past that you can create additional AppDomains within an application and then load assemblies into the AppDomains instead of the main application, then you can dispose of the AppDomain and associated references/assemblies and I am hoping... handles?

Note - I know that I am calling Nuget package restore above, but stepping through the code, I can definitively say that the locking occurs at the build step, not the nuget restore.

2

There are 2 best solutions below

0
On

I had a similar issue once but, not using BuildManager, I've used a build file and when running the msbuild process I've noticed a similar error.

When I looked in Task Manager I've noticed that there were several msbuild processes which held some files locked.

This is because msbuild has something called nodereuse that will keep some of the process active so that further builds will be faster.

If you want to disable this you can use the following msbuild parameter:

/nodeReuse:value OR /nr:value
Enable or disable the re-use of MSBuild nodes.
You can specify the following values:

  • True. Nodes remain after the build finishes so that subsequent builds can use them (default).
  • False. Nodes don't remain after the build completes.

A node corresponds to a project that’s executing. If you include the /maxcpucount switch, multiple nodes can execute concurrently.

After I set this parameter to false all my locked files issues were gone. Maybe this will help you too.

3
On

You might want to call BuildManager.DefaultBuildManager.EndBuild() before you dispose it, as this will signal that "no more build requests are expected (or allowed) and that the BuildManager may clean up"