1

我正在执行以下代码:

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 恢复。

4

2 回答 2

1

我曾经遇到过类似的问题,但是我没有使用 BuildManager,而是使用了构建文件,并且在运行该msbuild过程时我注意到了类似的错误。

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

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

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

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

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

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

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

于 2017-11-06T10:48:13.307 回答
1

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

于 2017-11-06T10:55:51.553 回答