MSBuild“无法删除目录”

12

我们的一个CruiseControl.NET项目出现了间歇性失败的情况,因为一项msbuild任务失败并显示以下错误:

error MSB3231:无法删除目录“d:\ Somewhere \ Dir \ Admin”。 参数不正确。

对应的msbuild脚本行只是:

<RemoveDir Directories="$(DistributionDir)\Admin" Condition="Exists('$(DistributionDir)\Admin')" />
当我查看失败构建后的状态时,目录内容已成功删除,但空目录本身仍然存在。通常下一次构建会成功(只需删除空目录)。请注意,问题似乎不是通常的“某些其他进程(如杀毒软件)保持锁定目录”,错误不是“拒绝访问”,而是非常奇怪的“参数不正确”。我使用SysInternals Process Monitor监视构建过程,结果很奇怪-一切都按预期进行,目录内容被枚举、删除,当顶层目录枚举以“NO MORE FILES”结束时,目录关闭了,然后......没有其他操作到达进程监视器:
10:04:09,9190557    MSBuild.exe 3516    QueryDirectory  D:\Somewhere\Dir\Admin  NO MORE FILES   
10:04:09,9190928    MSBuild.exe 3516    CloseFile       D:\Somewhere\Dir\Admin  SUCCESS 
下一次(成功)构建尝试只是一个无聊的成功目录删除。
10:31:21,8616463    MSBuild.exe 1760    CreateFile  D:\Somewhere\Dir\Admin  SUCCESS Desired Access: Read Data/List Directory, Synchronize, Disposition: Open, Options: Directory, Synchronous IO Non-Alert, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened
10:31:21,8616861    MSBuild.exe 1760    QueryDirectory  D:\Somewhere\Dir\Admin\*    SUCCESS Filter: *, 1: .
10:31:21,8617305    MSBuild.exe 1760    QueryDirectory  D:\Somewhere\Dir\Admin  SUCCESS 0: ..
10:31:21,8617589    MSBuild.exe 1760    QueryDirectory  D:\Somewhere\Dir\Admin  NO MORE FILES   
10:31:21,8618209    MSBuild.exe 1760    CloseFile   D:\Somewhere\Dir\Admin  SUCCESS 
10:31:21,8621579    MSBuild.exe 1760    CreateFile  D:\Somewhere\Dir\Admin  SUCCESS Desired Access: Read Attributes, Delete, Synchronize, Disposition: Open, Options: Directory, Synchronous IO Non-Alert, Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened
10:31:21,8622118    MSBuild.exe 1760    QueryAttributeTagFile   D:\Somewhere\Dir\Admin  SUCCESS Attributes: D, ReparseTag: 0x0
10:31:21,8622408    MSBuild.exe 1760    SetDispositionInformationFile   D:\Somewhere\Dir\Admin  SUCCESS Delete: True
10:31:21,8622676    MSBuild.exe 1760    CloseFile   D:\Somewhere\Dir\Admin  SUCCESS 

似乎由于某种原因,MSBuild/Windows 在执行目录删除之前检测到某种无效参数错误,但我不知道该去哪里寻找。(我也尝试运行了 chkdsk,但没有发现任何问题。我还删除并重新创建了父级 D:\Somewhere\Dir 目录,但仍然没有改变。)

那么,您有任何想法可以指出问题所在或者如何进一步进行调查吗?

(我不确定这个问题应该放在哪里,它可能介于 SO、Progs SE、Server Fault 和 Superuser 之间...)


如果您删除条件会发生什么?RemoveDir默认情况下设置为ContinueOnError。 - Ritch Melton
@Ritch Melton - 看起来ContinueOnError不是默认的,添加ContinueOnError有所帮助,见下文。 - Mormegil
我改正了。对于错误的信息感到抱歉。 - Ritch Melton
5个回答

9
尝试了很多方法,但是我无法弄清为什么当目录不为空时有时会失败;在我们的情况下,目录包含符号链接。无论如何,我不喜欢使用ContinueOnError,因为这意味着当出现实际错误时,您不会知道它,或者必须在每个RemoveDir之后进行额外的检查,例如<Error Condition="Exists...。我们现在使用的解决方案是显式清空目录,之后msbuild似乎没有任何问题将其删除:
<MSBuild.ExtensionPack.FileSystem.Folder Condition="Exists( $(PathtoEmpty) )"
   TaskAction="RemoveContent" Path="$(PathtoEmpty)" />
<RemoveDir Directories="$(PathtoEmpty)" />

9

我无法确定为什么它失败了,但如果文件夹是唯一剩下的东西,那么构建是否可以正确完成?如果可以的话,一种解决方法是指定ContinueOnError="True"。


我之前也遇到了同样的问题,而这就是我不得不采用的解决方案。 - skolima
这似乎有所帮助!一个简单的想法巧妙地绕过了问题,我之前没有想到过!谢谢! - Mormegil

6

我刚遇到了这个错误,后来发现是因为我在Windows资源管理器中打开了有问题的文件夹,导致它无法被正确删除。


3
也许有点晚了,但我发现了同样的错误,问题似乎在Exists条件中。似乎该条件的评估没有正确地释放目录,与任务执行产生冲突。
通过删除条件,如果存在,则将删除目录,但该语句不会因不存在而失败:

<RemoveDir Directories="$(DistributionDir)\Admin" />


1
所选答案似乎是一种欺骗行为,因为它会阻止您获取可能是关键错误的实际错误信息。
我可以使用删除内容而不是删除目录,如下所示。
 <MSBuild.ExtensionPack.FileSystem.Folder Condition="Exists( $(OutputPath) )"   TaskAction="RemoveContent" Path="$(OutputPath)" />

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接