MSBuild и TeamBuild - сбой BuildInParallel из-за нарушения прав доступа к файлу MSB3021

Я поддерживаю сборку довольно большого программного обеспечения, состоящего примерно из 350 проектов csharp. Наше время сборки для встроенной отладки составляет около 17 минут.

Я искал способы сократить время сборки, и свойство BuildInParallel выглядело интригующим. Тем более, что у нас есть четырехъядерный сервер, выполняющий наши сборки, он действительно должен иметь возможность использовать преимущества вычислительной мощности.

Но, увы ... После установки свойства, изменения файла конфигурации для агента сборки и его перезапуска, первый запуск действительно выглядел многообещающим, намного быстрее, чем обычно, вплоть до момента, когда он потерпел неудачу.

После просмотра журналов сборки кажется, что сборка завершается неудачей, когда она пытается скопировать ссылки, помеченные как CopyLocal = true, в выходной каталог. Если проект C # A и проект C # B построены параллельно, и оба ссылаются на одну и ту же стороннюю dll и пытаются скопировать ее одновременно, второй процесс, пытающийся скопировать файл, получит нарушение доступа к файлу - файл используется другим процессом.

Кто-нибудь испытал это и смог получить многопроцессорные сборки, работающие над Team Build?


Вот одна из неудач: сложно понять, какой еще проект строился в то же время.

Я удалил все ненужное:

54> Целевой объект «_CopyFilesMarkedCopyLocal» в файле «c: \ WINDOWS \ Microsoft.NET \ Framework \ v3.5 \ Microsoft.Common.targets» из проекта «d: \ temp \ PCM \ 1.3-Maint_CI \ Sources \ Modules \ Core \ Test \ UnitTest \ TestDIPS.Core.Data.Server.NUnit \ TestDIPS.Core.Data.Server.NUnit.csproj ": 54> Задача" Копировать "Копирование файла из" .......... \ Bin \ 3rdParty \ Oracle \ Oracle.DataAccess.dll "в" d: \ temp \ PCM \ 1.3-Maint_CI \ Binaries \ Debug \ Oracle.DataAccess.dll ". Команда: copy / y ".......... \ Bin \ 3rdParty \ Oracle \ Oracle.DataAccess.dll" "d: \ temp \ PCM \ 1.3-Maint_CI \ Binaries \ Debug \ Oracle.DataAccess.dll "54> c: \ WINDOWS \ Microsoft.NET \ Framework \ v3.5 \ Microsoft.Common.targets (2703,9): ошибка MSB3021: невозможно скопировать файл" .......... \ Bin \ 3rdParty \ Oracle \ Oracle.DataAccess.dll "в" d: \ temp \ PCM \ 1.3-Maint_CI \ Binaries \ Debug \ Oracle.DataAccess.dll ". Процесс не может получить доступ к файлу 'd: \ temp \ PCM \ 1.3-Maint_CI \ Binaries \ Debug \ Oracle.DataAccess.dll', потому что он используется другим процессом. Готово, выполнение задачи «Копировать» - НЕ выполнено. 54> Выполнено построение цели «_CopyFilesMarkedCopyLocal» в проекте «TestDIPS.Core.Data.Server.NUnit.csproj» - НЕ ИСПОЛЬЗУЕТСЯ.


person Erling Paulsen    schedule 01.04.2009    source источник


Ответы (6)


Целевые объекты по умолчанию, которые поставляются с MSBuild, предназначены для поведения CopyLocal - это то, на что полагается VS. CopyLocal проблематично, когда вы выводите в единственный выходной каталог.

Чтобы иметь возможность по-настоящему строить параллельно, вам необходимо отключить несколько специфических для CopyLocal поведений в файлах Microsoft. *. Common. *. Target. Я разговаривал с некоторыми людьми из команды MSBuild в прошлом, и это особенно непросто. Даже если вы отключите какое-то поведение CopyLocal, тестовые аксессоры VS не будут хорошо себя вести при параллельной сборке.

Вот с чего можно начать:

  1. Отключите поведение CopyLocal для ссылок, установив для private значение true.
  2. Отключите CopyLocal для файлов CopyToOutputPath при построении зависимых проектов.
person gokult    schedule 30.04.2009
comment
Приносим извинения за поздний ответ, но большое спасибо за разъясняющий ответ. Ваш ответ соответствует моим последним выводам, у меня были проблемы с тестовыми аксессуарами. Я обнаружил, что мне придется либо изгнать тестовые средства доступа, либо изменить целевой файл, чего мы не хотим делать. Надеюсь, это будет исправлено в Team Build 2010 / .Net 4.0. - person Erling Paulsen; 19.05.2009

У задачи MS Build Copy есть недокументированная функция, по крайней мере, Google хранит молчание. Если установить общесистемную переменную среды MSBUILDALWAYSRETRY = 1 Эта задача будет пытаться скопировать файл, даже если он получит исключение «Доступ запрещен» во время операции копирования.

Пример вывода

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets (3513): Got System.UnauthorizedAccessException: Access to the path 'C:\Builds\8\28\Binaries\Release\fr\System.Spatial.resources.dll' is denied.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)
   at System.IO.File.Copy(String sourceFileName, String destFileName, Boolean overwrite)
   at Microsoft.Build.Tasks.Copy.CopyFileWithLogging(FileState sourceFileState, FileState destinationFileState)
   at Microsoft.Build.Tasks.Copy.DoCopyWithRetries(FileState sourceFileState, FileState destinationFileState, CopyFileWithState copyFile) copying C:\Builds\8\28\Sources\Main\Solutions\packages\System.Spatial.5.2.0\lib
et40\fr\System.Spatial.resources.dll to C:\Builds\8\28\Binaries\Release\fr\System.Spatial.resources.dll and HR is -2147024891
 C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets (3513): Retrying on ERROR_ACCESS_DENIED because MSBUILDALWAYSRETRY = 1
 C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets (3513): Could not copy "C:\Builds\8\28\Sources\Main\Solutions\packages\System.Spatial.5.2.0\lib
et40\fr\System.Spatial.resources.dll" to "C:\Builds\8\28\Binaries\Release\fr\System.Spatial.resources.dll". Beginning retry 1 in 1000ms. Access to the path 'C:\Builds\8\28\Binaries\Release\fr\System.Spatial.resources.dll' is denied.
person Nick Kashtanov    schedule 23.03.2013
comment
Ссылка не работает - person Shmil The Cat; 24.09.2017

У меня такая же проблема много месяцев назад.

Существует два типа копирования файлов в файлах проекта VS C # (файлы .csproj):

  1. Связанные сборки, у которых есть свойство «Копировать локально». когда свойство имеет значение True, сборка копируется в выходной путь.

  2. Дополнительные файлы, у которых есть свойство «Копировать в выходной каталог». когда для свойства установлено значение «копировать всегда» или «копировать, если новее», файл копируется в выходной путь.

проблема:

A: Если два или более проекта создаются одновременно, и два из них пытаются скопировать один и тот же файл в выходной каталог, вы можете столкнуться с такими ошибками, как «ошибка MSB3021: невозможно скопировать файл», «Доступ к пути запрещен». , «Процесс не может получить доступ к файлу» и т. Д.

B: Если два или более проектов ссылаются на общий проект, который имеет некоторые элементы типа 2. В этом случае во время параллельной сборки проектов два из них могут одновременно пытаться построить цель GetCopyToOutputDirectoryItems для общего проекта. Так что вы снова можете столкнуться с вышеуказанными исключениями.

Решение1:

заставить OutputPath разных файлов .csproj не находиться в одном и том же пути

http://social.msdn.microsoft.com/Forums/is/tfsbuild/thread/a62a6f98-ec44-46c1-a0d0-7f441f0db973.

решение2:

Шаг 1. Решение состоит в том, чтобы установить свойство общих элементов (значение «Ложь» в случае 1 и «Не копировать» в случае 2) для всех этих общих элементов, кроме одного, в ваших проектах. или удалите их, если есть возможность.

Чтобы найти возможные ошибки, вы можете выполнить поиск по словам «частный» (для случая 1) и «CopyToOutputDirectory» (для случая 2) в файлах * .csproj.

Шаг 2: ...

Удачи

person Shahyad Sharghi    schedule 23.11.2009

Похоже, что ваши проекты настроены на один и тот же выходной каталог. Если вы настроите Project A и Project B для вывода в разные каталоги, это решит эту ошибку.

person Community    schedule 23.04.2009
comment
Да, но это поведение по умолчанию для TeamBuild, и я не хочу его менять, если нет другого способа обойти это. - person Erling Paulsen; 27.04.2009

Это также может произойти из-за того, что файл доступен только для чтения. В этих случаях (т. Е. Не тех, которые описаны в большинстве других ответов), существуют подходящие обходные пути, которые различаются в зависимости от того, можете ли вы полагаться на MSBuild 3.5 или более позднюю версию.

person Ruben Bartelink    schedule 24.11.2009
comment
Хотя теоретически это может дать ответ на вопрос, было бы предпочтительнее включить сюда основные части ответа и предоставить ссылку для справки. Я сейчас удаляю это, если вы добавите соответствующие детали, отметьте это для внимания модератора. - person NullUserException; 29.03.2012

Какой компилятор вы используете? Насколько мне известно, до VS2005 параллельная сборка не работала для нескольких проектов. Это известная проблема, которую MS постоянно заявляет, что они в конечном итоге исправят ее, но я понятия не имею, действительно ли они решили ее в VS2008.

person Tal Pressman    schedule 23.04.2009
comment
Мы полностью на TFS2008, как клиенты, так и сервер сборки - person Erling Paulsen; 27.04.2009