使用BuildManager构建项目会导致nuget包DLL被锁定

时间:2017-11-03 16:02:59

标签: c# .net msbuild-task buildmanager

我正在执行以下代码:

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;
}

但是当构建任务完成时,当我尝试删除文件夹时 - 我无法这样做,因为我的应用程序已经从解决方案包文件夹中将DLL加载到内存中。

具体地 Microsoft.Bcl.Build.Tasks.dll

因为这个文件最终在我的应用程序中“正在使用”,所以我的应用程序在应用程序关闭之前无法删除临时目录。
鸡肉和鸡蛋 - 我不想在文件夹消失之前关闭应用程序,在应用程序关闭之前我无法删除该文件夹。

任何人都有任何已知有效的解决方案吗? 例如:
我知道,一旦在应用程序中加载了DLL,它就是永久性的,并且不能传统地释放 但是 - 我过去听说你可以在一个应用程序中创建额外的AppDomain然后将程序集加载到AppDomain而不是主应用程序,然后你可以处理AppDomain和相关的引用/程序集,我希望...句柄?

注意 - 我知道我正在调用上面的Nuget包恢复,但是逐步执行代码,我可以明确地说锁定发生在构建步骤,而不是nuget恢复。

2 个答案:

答案 0 :(得分:1)

我有一个类似的问题,但是,不使用BuildManager,我使用了构建文件,在运行msbuild进程时,我注意到了类似的错误。

当我查看任务管理器时,我注意到有几个msbuild进程锁定了一些文件。

这是因为msbuild有一些名为nodereuse的东西会使某些进程保持活动状态,以便进一步构建更快。

如果要禁用此功能,可以使用以下msbuild参数:

  

/ nodeReuse:value / nr:value
  启用或禁用MSBuild节点的重用   您可以指定以下值:

     
      
  • 真。构建完成后节点仍然存在,以便后续构建可以使用它们(默认)。
  •   
  • 假。构建完成后,节点不会保留。
  •   
     

节点对应于正在执行的项目。如果包含/ maxcpucount开关,则可以同时执行多个节点。

将此参数设置为false后,我所有锁定的文件问题都消失了。也许这对你也有帮助。

答案 1 :(得分:1)

您可能希望在处置它之前调用BuildManager.DefaultBuildManager.EndBuild(),因为这将表示“不再需要(或允许)构建请求,并且BuildManager可能会清理”