67

我正在使用 TFS 2012 Build 并遇到错误

访问路径被拒绝

正在构建的解决方案包含大约 15 个项目,其中一些项目正在使用 Castle.Components.Validator.2.5.0 程序集。

我看过其他关于 TFS Build Access Denied 错误的帖子,但它们通常指的是同时运行构建。在这种情况下,一次只运行一个构建。此外,当服务器重新启动或构建有一段时间没有运行时,也会发生错误。

一旦构建运行并失败,下一个会成功,之后的每一个都会再次成功,直到构建有一段时间没有运行或服务器重新启动。虽然我们可以解决这个问题,但这是一个令人头疼的手动操作。

这是错误:

C:\WINDOWS\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Common.targets (3513):无法复制文件“D:\Builds\12\Foo\Check-In Build\Sources\packages\Castle.Components .Validator.2.5.0\lib\NET40\Castle.Components.Validator.dll”到“D:\Builds\12\Foo\Check-In Build\Binaries\Castle.Components.Validator.dll”。

拒绝访问路径“D:\Builds\12\Foo\Check-In Build\Binaries\Castle.Components.Validator.dll”。

查看日志文件时,您可以看到构建正在尝试复制文件两次。因为第一个锁定了文件,所以第二个失败,因此构建失败。这是显示正在发生的事情的日志文件片段:

2>_CopyFilesMarkedCopyLocal:将文件从“D:\Builds\12\Foo\Check-In Build\Sources\packages\Castle.Components.Validator.2.5.0\lib\NET40\Castle.Components.Validator.dll”复制到“ D:\Builds\12\Foo\Check-In Build\Binaries\Castle.Components.Validator.dll”。

5>_CopyFilesMarkedCopyLocal:将文件从“D:\Builds\12\Foo\Check-In Build\Sources\packages\Castle.Components.Validator.2.5.0\lib\NET40\Castle.Components.Validator.dll”复制到“ D:\Builds\12\Foo\Check-In Build\Binaries\Castle.Components.Validator.dll”。

2>_CopyFilesMarkedCopyLocal:将文件从“D:\Builds\12\Foo\Check-In Build\Sources\packages\MvcContrib.Mvc3.FluentHtml-ci.3.0.96.0\lib\MvcContrib.FluentHtml.dll”复制到“D: \Builds\12\Foo\Check-In Build\Binaries\MvcContrib.FluentHtml.dll”。将文件从“D:\Builds\12\Foo\Check-In Build\Sources\packages\RhinoMocks.3.6\lib\Rhino.Mocks.dll”复制到“D:\Builds\12\Foo\Check-In Build\二进制文件\Rhino.Mocks.dll”。

任何有关如何解决此问题的帮助将不胜感激。

4

16 回答 16

51

正如其他人提到的,当使用公共目标目录执行多线程构建并且文件复制任务碰巧遇到与为不同项目运行的复制任务同时发生冲突时,会发生这种情况。

通常这会导致“文件被另一个进程使用”异常(由文件复制任务处理和重试),但有时文件操作会导致“访问被拒绝”异常。(我仍然不确定为什么)

有人建议您应该“解决重复问题”,但对于所有项目都需要直接引用 log4net 之类的库的情况,我认为这不可行。

显然,防止该问题的一种方法是使用/p:BuildInParallel=falseor/m:1/maxcpucount:1(或完全省略参数)显式运行 msbuild 以强制单线程模式。

但是,在 TFS 2013中,默认构建模板总是自动传递/m(使用所有内核)到 msbuild,它会默默地覆盖您可以手动传递的任何单线程设置。(由我自己的实验和检查诊断日志确定)

我尝试的另一个解决方法是手动传递/p:AllowedReferenceRelatedFileExtensions=none给 msbuild,这样可以防止从引用的库中复制所有 pdb 和 xml 文件。(因为有一段时间我只看到 xml 文件有这个问题。)但后来我一直遇到 log4net.dll 的问题。

我使用的最终解决方法是通过反编译源代码发现的Microsoft.Build.Tasks.Copy

if (hrForException == -2147024891)
{
    if (!Copy.alwaysRetryCopy)
        throw;
    else
        this.LogDiagnostic("Retrying on ERROR_ACCESS_DENIED because MSBUILDALWAYSRETRY = 1", new object[0]);
}

如果发生错误 -2147024891(0x80070005 访问被拒绝),复制任务将检查一个特殊变量以查看它是否应该重试。该值是通过环境变量设置的:

Copy.alwaysRetryCopy = Environment.GetEnvironmentVariable("MSBUILDALWAYSRETRY") != null;

设置环境变量 MSBUILDALWAYSRETRY = 1(并重新启动构建服务器)后,问题就消失了。而且我还定期开始在构建日志中看到“Retrying on ERROR_ACCESS_DENIED ...”作为警告,证明设置正在生效,(而不是构建只是巧合成功)。

(请注意,此环境变量没有很好的文档记录,请酌情使用。)

更新:显然 TFS 2015 不再覆盖您的/m:1with /m(即使在旧版/XAML 构建定义上),这应该/m:1再次进行有效修复。

于 2014-04-14T20:20:54.687 回答
41

看起来有两个项目在复制同一个文件。根据时间的不同,它们有时会同时发生,从而导致失败。您必须追溯节点 ID 才能找到源项目。有关更多详细信息和可能跟踪的代码,请参阅http://blogs.msdn.com/b/buckh/archive/2012/01/21/a-tool-to-find-duplicate-copies-in-a-build.aspx给你。

于 2012-10-16T00:30:26.510 回答
13

正如 Buck Hodges 和 Nimblejoe 所说,这主要是由于 TFS 默认运行多个 MSBuild 进程来构建您的项目。

您可以在Process -> 3. Advanced -> MSBuild Arguments通过添加 MSBuild 参数/p:BuildInParallel=false在构建定义中覆盖它

于 2013-10-02T12:56:35.133 回答
11

如果您打开了构建代理的文件夹,也会发生这种情况。

于 2014-03-24T18:11:56.240 回答
8

我也有同样的问题。我收到与无法复制相关的错误消息,因为访问路径被拒绝。在我的情况下,我所有的 dll 和 xml 文件等都放在 D:\TFS\Example\Bin\Debug 文件夹中。

我右键单击 Bin 文件夹并单击属性并看到只读复选框在属性下被选中。

我取消选中只读复选框并单击应用并在显示的新弹出窗口上单击确定。

我回到 Visual Studio 并构建了我的解决方案,它给了我错误消息。

瞧……这一次它成功构建而没有错误。

我不知道这是否完美,但我这样做是为了解决我的问题。

于 2014-12-30T18:10:02.827 回答
3

要解决此问题,我必须删除源目录上的“ReadOnly”标志

只读

然后在构建定义集Clean Workspace

工作区

_

在此处输入图像描述

于 2018-02-13T16:32:00.307 回答
1

像 Ziggler 一样,我通过删除项目中 bin 文件夹的“只读”属性来解决这个问题。它只发生在存储在 /packages/ 目录中的 XML 文件上,该目录对于包含此项目的解决方案是通用的。“bin”文件夹未检入源代码管理。我仍然对问题的根本原因感到困惑。

于 2015-07-17T13:47:32.230 回答
1

我发现在构建尝试覆盖它在先前尝试构建时创建的“工作目录”中的文件后发生的相同问题。(在代理中设置)

我通过在尝试构建之前手动删除它创建的输出文件夹(在我的情况下为 [Working Directory]\Binaries)解决了这个问题。

这可以通过更改构建定义自动完成。在Process --- 2.Basic --- Clean Workspace下将其设置为Outputs选项

于 2015-09-24T05:15:22.950 回答
1

这是我必须处理的这个问题的一个变体:

我无法弄清楚为什么我的构建总是因为“拒绝访问路径”错误而失败,即使我已经在我的 XAML 构建的 MSBuild Arguments 中添加了/p:BuildInParallel=false和之类的东西。/p:OverwriteReadOnlyFiles=true原因原来是我的项目属性中的“构建后事件命令行”。

改变后

%WinDir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe[SNIP] 
/P:Configuration=$(ConfigurationName);[SNIP] 
;AutoParameterizationWebConfigConnectionStrings=false

%WinDir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe[SNIP] 
/P:Configuration=$(ConfigurationName);[SNIP]
;AutoParameterizationWebConfigConnectionStrings=false;OverwriteReadOnlyFiles=true

错误消失了。

于 2017-03-20T15:37:29.810 回答
0

一种可能的原因是,如果您将类库的bin或文件夹签入到 TFS 中。obj如果是这种情况,从 TFS 中删除项目的 bin 或 obj 文件夹将解决此问题。

于 2013-01-15T08:28:10.730 回答
0

我遇到了这个问题并选择忽略它,因为我不想为了摆脱 NuGet 的一些良性错误消息而牺牲构建性能。但是,我似乎在尝试解决另一个问题时偶然发现了一个解决方案,我认为这是相关的。我认为 NuGet 包的获取顺序与解决方案中项目的构建顺序有关。因此,如果这以某种方式变得脱节,那么在您遇到构建错误之前,NuGet 可能是第一个受害者,您开始收到“找不到元数据文件'XXX.dll'”错误,这烦人地要求您再次构建,直到构建成功(如此所述)。

因此,我认为解决方案是按照上述问题的公认答案中描述的步骤进行操作。或者,按照备选答案之一中更全面的步骤进行操作。换句话说,禁用所有项目的构建,重新启动 VS,然后重新启用所有项目的构建。这将(通常)解决构建顺序。这应该有望解决 NuGet 问题。请让我知道这是否可以为任何人解决。

于 2017-04-13T14:42:23.337 回答
0

我在使用 TFS 2015 时遇到了这个问题。原来是因为构建代理在默认(网络服务)凭据下运行,该凭据对目标文件夹没有写权限。一旦我删除了代理并使用凭据重新安装它,它就可以工作了。它确实让我浏览了一段时间的日志,检查和取消选中多进程框,甚至在我的搜索中重新启动构建服务器。首先检查明显的东西......

于 2017-09-27T15:16:31.353 回答
0

对我来说,构建代理不是在管理员 powershell 中启动的。

于 2018-07-19T08:33:33.297 回答
0

MSBuild 参数:- /tv:14.0 /t:Rebuild /m:1 /p:RunCodeAnalysis=false /p:TreatWarningsAsErrors=false /p:OverwriteReadOnlyFiles=true /p:BuildInParallel=false /p:AllowedReferenceRelatedFileExtensions=none

强文本

  1. 将 false 设置为清理工作区
  2. 转到构建代理并从映射文件夹中删除只读。
于 2021-05-11T06:14:24.610 回答
-1

正如很多人之前已经说过的那样,在并行构建项目时会发生这种情况。项目 A 和 B 都引用第 3 方库 C(本地复制)将在同时构建时导致此问题 - 并排。

真正的问题是,TFS Build 2012 及更低版本配置为在构建解决方案时,将解决方案的整个输出复制到单个文件夹。这就是并行构建的痛苦所在。

自 TFS 2013 起,您可以通过将构建定义中的“输出位置”设置为“PerProject”来轻松解决此问题。这会强制构建服务的行为类似于本地 msbuild 运行,其中有关输出位置的设置是从相应的项目文件中读取的。因此输出被写入每个项目下的 bin 文件夹。

对于 TFS 2012 及以下版本,本文(+链接文章)将帮助您获得与 TFS 2013 相同的结果:

http://blog.stangroome.com/2012/05/10/override-the-tfs-team-build-outdir-property-net-4-5/

于 2014-10-17T05:03:04.780 回答
-2

我通过关闭所有打开的 Visual Studio 实例、重新打开解决方案并再次构建它解决了一个非常类似的问题。

于 2014-11-06T03:14:32.473 回答