【问题标题】:msbuild “Unable to remove directory”msbuild“无法删除目录”
【发布时间】:2011-09-22 15:58:32
【问题描述】:

我们的一个 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、Server Fault、Superuser 之间……)

【问题讨论】:

  • 如果删除条件会发生什么? RemoveDir 默认设置了 ContinueOnError。
  • @Ritch Melton - ContinueOnError 似乎不是默认值,添加 ContinueOnError 有所帮助,见下文。
  • 我的立场是正确的。很抱歉提供了不好的信息。

标签: msbuild cruisecontrol.net


【解决方案1】:

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

【讨论】:

  • 我前段时间遇到了同样的问题,这是我不得不接受的解决方案。
  • 这似乎有帮助!一个简单的想法很好地回避了这个问题,我只是没有想到!谢谢!
【解决方案2】:

尝试了很多东西,但我不明白为什么当目录不为空时有时会失败;在我们的例子中,如果重要的话,目录包含符号链接。无论如何,我不喜欢使用ContinueOnError,因为这意味着当出现您不知道的实际错误时,或者必须在每个RemoveDir 之后进行像&lt;Error Condition="Exists... 这样的额外检查。我们现在使用的解决方案是明确清空目录,之后 msbuild 删除它似乎没有任何问题:

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      可能这有点晚了,但我发现了同样的错误,问题似乎在存在条件下。似乎条件的评估不会以某种方式释放与任务执行冲突的目录。
      通过删除条件,如果目录存在则将被删除,但如果不存在则语句不会失败:

      &lt;RemoveDir Directories="$(DistributionDir)\Admin" /&gt;

      【讨论】:

        【解决方案5】:

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

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

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

        【讨论】:

          猜你喜欢
          • 2011-03-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多