msbuild «Невозможно удалить каталог» - PullRequest
11 голосов
/ 22 сентября 2011

Один из наших проектов 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…)

Ответы [ 5 ]

9 голосов
/ 23 сентября 2011

Я не могу сказать, почему происходит сбой, но если папка - единственное, что осталось, может ли сборка завершиться правильно? Если это так, то для обхода этой проблемы необходимо указать ContinueOnError = "True".

6 голосов
/ 07 июля 2013

Многое перепробовал, но я не мог понять, почему это иногда не получается, когда каталог не пустой; в нашем случае каталог содержит символические ссылки, если это имеет значение. В любом случае, я не люблю использовать ContinueOnError, так как это означает, что когда есть реальная ошибка, вы ее не знаете или должны делать дополнительную проверку, например <Error Condition="Exists... после каждого RemoveDir. Решение, которое мы используем сейчас, заключается в том, чтобы явно очистить каталог, после чего msbuild, похоже, не имеет проблем с его удалением:

<MSBuild.ExtensionPack.FileSystem.Folder Condition="Exists( $(PathtoEmpty) )"
   TaskAction="RemoveContent" Path="$(PathtoEmpty)" />
<RemoveDir Directories="$(PathtoEmpty)" />
5 голосов
/ 23 апреля 2015

Я только что столкнулся с этой ошибкой сам, оказалось, что у меня открылась папка, которая нарушала работу в проводнике Windows, и это помешало ее правильному удалению.

2 голосов
/ 18 апреля 2013

Может быть, это немного поздно, но я обнаружил ту же ошибку, и проблема, похоже, в состоянии Exists. Кажется, что оценка условия каким-то образом не освобождает каталог должным образом, конфликтуя с выполнением задачи.
При удалении условия каталог будет удален, если он существует, но оператор не будет выполнен, если он не существует:

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

0 голосов
/ 14 декабря 2016

Выбранный ответ кажется взломанным, поскольку он не дает вам получить фактическую ошибку, которая может быть критической ошибкой.

Я мог бы использовать удаление содержимого вместо удаления каталога, как показано ниже.

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