msbuild“无法删除目录”

发布于 2024-12-06 03:52:26 字数 2379 浏览 1 评论 0原文

我们的 CruiseControl.NET 项目之一不断间歇性失败,因为 msbuild 任务失败并显示

错误 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、服务器故障、超级用户之间……)

One of our CruiseControl.NET projects keeps intermittently failing because a msbuild task fails with

error MSB3231: Unable to remove directory "d:\Somewhere\Dir\Admin". The parameter is incorrect.

The corresponding msbuild script line is just

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

When I look at the state after the failed build, the directory contents was removed successfully, but the empty directory itself is left there. And the next build usually succeeds (having to remove just the empty directory). Note that the problem does not seem to be the usual “some other process (like antivirus) keeps locking the directory”, the error is not “access denied”, but a very strange “the parameter is incorrect”.

I monitored the build with SysInternals Process Monitor, and the result is strange – everything goes as expected, the contents of the directory is enumerated, deleted, and when the top-level directory enumeration finishes with “NO MORE FILES”, the directory is closed, and… nothing. No other operation gets to the process monitor:

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 

The next (successful) build attempt is just a boring successful directory removal:

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 

It seems for some reason, MSBuild/Windows detects some kind of invalid parameter error before the directory removal is executed, but I have no idea where to look. (I have also tried to run chkdsk, nothing was found. I have also removed and recreated the parent D:\Somewhere\Dir directory, nothing changed.)

So – any idea where the problem could be or how should I investigate further?

(I am not sure where this question should have gone, it is kind of somewhere between SO, Progs SE, Server Fault, Superuser…)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

蓝海 2024-12-13 03:52:26

我不能说它为什么失败,但如果该文件夹是唯一剩下的东西,构建能否正确完成?如果是这样,解决方法是指定ContinueOnError="True"。

I can't say why it is failing, but if the folder is the only thing left over can the build complete correctly? If so, a workaround would be to specify ContinueOnError="True".

渡你暖光 2024-12-13 03:52:26

尝试了很多方法,但我不明白为什么当目录不为空时有时会失败;在我们的例子中,如果重要的话,目录包含符号链接。无论如何,我不喜欢使用 ContinueOnError 因为这意味着当存在实际错误时您不知道它,或者必须进行额外的检查,例如

<MSBuild.ExtensionPack.FileSystem.Folder Condition="Exists( $(PathtoEmpty) )"
   TaskAction="RemoveContent" Path="$(PathtoEmpty)" />
<RemoveDir Directories="$(PathtoEmpty)" />

Tried a lot of things, but I couldn't figure out why this sometimes fails when the directory isn't empty; in our case the directory contains symbolic links if that matters. Anyway I don't like using ContinueOnError since that means when there is an actual error you don't know it, or have to do an extra check like <Error Condition="Exists... after every RemoveDir. The solution we use now is to explicitely empty the directory, after which msbuild doesn't seem to have any problems removing it:

<MSBuild.ExtensionPack.FileSystem.Folder Condition="Exists( $(PathtoEmpty) )"
   TaskAction="RemoveContent" Path="$(PathtoEmpty)" />
<RemoveDir Directories="$(PathtoEmpty)" />
过去的过去 2024-12-13 03:52:26

我自己刚刚遇到过这个错误,结果是我在 Windows 资源管理器中打开了有问题的文件夹,导致它无法被正确删除。

I've just encountered this error myself, it turned out that I had the offending folder opened in a Windows Explorer and that prevented it from being properly deleted.

那些过往 2024-12-13 03:52:26

可能这来得有点晚了,但我发现了同样的错误,而且问题似乎出在“存在”条件下。似乎对条件的评估在某种程度上没有释放与任务执行冲突的目录。
通过删除条件,目录将被删除(如果存在),但如果不存在则语句不会失败:

May be this comes a little late, but I found the same error and the problem appears to be in the Exists condition. It seems that the evaluation of the condition somehow doesn't release the directory properly conflicting with the execution of the task.
By removing the condition the directory will be removed if it exists but the statement won't fail if it doesn't exist:

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

◇流星雨 2024-12-13 03:52:26

所选答案似乎是一个黑客,因为它阻止您获得可能是严重错误的实际错误。

我可以使用删除内容而不是删除目录,如下所示。

 <MSBuild.ExtensionPack.FileSystem.Folder Condition="Exists( $(OutputPath) )"   TaskAction="RemoveContent" Path="$(OutputPath)" />

The selected answer seems to be a hack,as it stops you from getting the actual error which might be a critical error.

I could use remove content instead of removing the directory as below.

 <MSBuild.ExtensionPack.FileSystem.Folder Condition="Exists( $(OutputPath) )"   TaskAction="RemoveContent" Path="$(OutputPath)" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文