TFS 2012构build“访问path被拒绝”
我正在使用TFS 2012构build并运行到一个错误
访问path被拒绝
正在构build的解决scheme包含大约15个项目,其中一些正在使用Castle.Components.Validator.2.5.0程序集。
我已经看到其他职位,谈论TFS构build访问被拒绝的错误,但他们通常指的是同时构build运行。 在这种情况下,一次只能运行一个构build。 此外,服务器重新启动或生成未运行一段时间时发生错误。
一旦构build运行失败,下一个成功,然后每一个成功,直到构build尚未运行一段时间或服务器重新启动。 虽然我们可以解决这个问题,但这是一个手动的头痛。
这是错误:
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“。
访问path“D:\ Builds \ 12 \ Foo \ Check-In Build \ Binaries \ Castle.Components.Validator.dll”被拒绝。
查看日志文件时,可以看到构build正在尝试复制文件两次。 因为第一个文件上有一个锁,第二个失败,因此构build失败。 这是日志文件的一个片段,显示了正在发生的事情:
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”。
任何帮助如何解决这个将不胜感激。
它看起来像有两个项目复制相同的文件。 根据时间的不同,他们有时会同时发生,导致失败。 您必须追踪节点id以find源项目。 请参阅http://blogs.msdn.com/b/buckh/archive/2012/01/21/a-tool-to-find-duplicate-copies-in-a-build.aspx了解可能跟踪的更多详细信息和代码它为你降下。;
正如其他人提到的,这发生在使用公共目标目录执行multithreading构build时,并且文件复制任务碰巧与运行不同项目的副本任务碰巧同时发生冲突。
通常这应该导致“由另一个进程使用的文件”exception(由文件复制任务处理并重试),但有时文件操作导致“访问被拒绝”exception。 (我还不确定为什么)
有人build议你“解决重复”,但是我不认为这是可行的,所有的项目都需要直接引用像log4net这样的库。
显然,防止此问题的一种方法是使用/p:BuildInParallel=false
或/m:1
或/maxcpucount:1
(或完全省略参数)显式运行msbuild以强制使用单线程模式。
但是,在TFS 2013中 ,默认构build模板自动总是将/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访问被拒绝)发生,复制任务将检查一个特殊的variables,看看它是否应该重试。 该值通过环境variables设置:
Copy.alwaysRetryCopy = Environment.GetEnvironmentVariable("MSBUILDALWAYSRETRY") != null;
设置环境variablesMSBUILDALWAYSRETRY = 1(并重新启动生成服务器)后,问题就消失了。 而且我还定期开始在构build日志中看到“正在重试ERROR_ACCESS_DENIED …”作为警告,certificate该设置正在生效,而不是构build只是巧合成功。
(请注意,这个环境variables没有很好的文档logging,根据需要使用。)
更新:显然,TFS 2015不再使用/m
(即使在legacy / XAML构build定义)覆盖/m:1
,这应该使/m:1
成为有效的修复。
正如Buck Hodges和Nimblejoe所说的,这主要是由于TFS默认运行多个MSBuild进程来构build项目。
您可以在Process – > 3中的构build定义中覆盖它。高级 – > MSBuild参数通过添加MSBuild参数/ p:BuildInParallel = false
如果您打开了构build代理的文件夹,也会发生这种情况。
我也有同样的问题。 我得到相关的错误消息,因为访问path被拒绝不能复制。 在我的情况下,我所有的DLL和XML文件等都放在D:\ TFS \ Example \ Bin \ Debug文件夹。
我右键单击Bin文件夹并单击属性,并看到属性下选中只读checkbox。
我取消选中“只读”checkbox并点击“应用”,并在显示的新popup窗口中单击“确定”。
我回到Visual Studio,并build立我的解决scheme,给了我错误消息。
Voilaa这一次,它成功build造没有错误。
我不知道这是否完美,但我这样做是为了解决我的问题。
像Ziggler一样,我通过删除项目中bin文件夹的“只读”属性来构build项目,解决了这个问题。 只有存储在包含此项目的解决scheme中通用的/ packages /目录中的XML文件才会发生这种情况。 “bin”文件夹没有被选入源代码控制。 我仍然难以解决问题的根源。
我发现在构build试图覆盖在之前尝试构build的“工作目录”中创build的文件之后发生的相同问题。 (在代理中设置)
我通过手动删除它创build的输出文件夹(在我的例子中[Working Directory] \ Binaries)解决这个问题,然后再尝试构build。
这可以通过更改构build定义自动完成。 在Process — 2.Basic — Clean Workspace下将其设置为Outputs选项
一个可能的原因是,如果您有用于登记到TFS的类库的bin
或obj
文件夹。 如果是这种情况,从TFS删除项目的bin或obj文件夹将解决此问题。
这是我不得不面对的这个问题的一个变种:
我无法弄清楚为什么我的构build保持在“访问path被拒绝”错误,即使我已经添加了像/p:BuildInParallel=false
和/p:OverwriteReadOnlyFiles=true
到我的XAML的MSBuild参数build立。 原因结果是我的项目属性中的“ 后生成事件命令行 ”。
改变后
%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
错误消失了。
我有这个问题,并select忽略它,因为我不想牺牲build设性能为了摆脱NuGet一些良性的错误消息。 然而,我似乎在试图解决另一个问题的时候偶然发现了一个解决scheme,我认为这是相关的。 我认为NuGet包的获取顺序与解决scheme中项目的构build顺序有关。 因此,如果这种方式已经脱节,那么NuGet可能会成为第一个在你发生构build错误之前发生的“无法find元数据文件”XXX.dll“的错误”,这些烦人的事情需要你重新构build,直到构build成功(如这里所述)。
所以,我相信解决办法是按照上述问题的接受答案中描述的步骤。 或者,按照其中一个备选答案中更全面的步骤进行操作。 换句话说,禁用所有项目的构build,重新启动VS,然后重新启用所有项目的构build。 这将(通常)parsing构build顺序。 这应该有希望解决NuGet问题。 请让我知道这是否为任何人修复。
我在TFS 2015中遇到了这个问题。事实certificate,这是因为构build代理程序在默认(NETWORK SERVICE)凭据下运行,该凭据对目标文件夹没有写入权限。 一旦我删除代理,并重新安装它的凭据它的工作。 它确实让我通过日志拖了一段时间,检查和取消选中多进程框,甚至在我的狩猎重新启动构build服务器。 首先检查明显的东西…
正如很多人之前已经说过的那样,在并行构build项目时会发生这种情况。 项目A和B都引用第三方库C(复制本地)将导致这一点,当他们在同一时间build立 – 并排。
真正的问题在于,TFS Build 2012及以下版本configuration为在构build解决scheme时将解决scheme的整个输出复制到单个文件夹。 这就是平行build造的痛苦源头。
从TFS 2013开始,您可以通过将构build定义中的“输出位置”设置为“PerProject”来轻松解决此问题。 这会强制构build服务的行为类似于本地的msbuild运行,从相应的项目文件中读取有关输出位置的信息。 所以输出被写入每个项目下的bin文件夹。
对于TFS 2012及以下本文(+链接的文章)将帮助您获得与TFS 2013相同的结果:
http://blog.stangroome.com/2012/05/10/override-the-tfs-team-build-outdir-property-net-4-5/
我通过closures所有打开的Visual Studio实例,重新打开解决scheme并重新构build它,解决了一个非常类似的问题。