Подтвердить что ты не робот

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

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

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

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

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

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


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

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

54 > Целевая "_CopyFilesMarkedCopyLocal" в файле "C:\WINDOWS\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets" от проекта "D:\Temp\PCM\1.3-Maint_CI\Sources\модули\Ядро\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\Бинарники\Debug\Oracle.DataAccess.dll" .      Команда:      copy/y "..........\Bin\3rdParty\Oracle\Oracle.DataAccess.dll" "D:\Temp\PCM\1.3-Maint_CI\Бинарники\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\Бинарники\Debug\Oracle.DataAccess.dll" . процесс не может получить доступ к файлу 'D:\Temp\PCM\1,3-Maint_CI\Binaries\Debug\Oracle.DataAccess.dll' потому что он используется другим процессом.     Выполнено выполнение задачи "Копировать" - FAILED. 54 > Готово создать цель "_CopyFilesMarkedCopyLocal" в проекте "TestDIPS.Core.Data.Server.NUnit.csproj" - FAILED.

4b9b3361

Ответ 1

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

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

Некоторые из вещей, которые вы можете начать с:

  • Отключить поведение CopyLocal для ссылок, установив private в true.
  • Отключить файлы CopyLocal для CopyToOutputPath при создании зависимых проектов.

Ответ 2

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

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

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.

Ответ 3

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

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

  • Связанные сборки, которые имеют свойство "Копировать локальное". когда свойство "Истина", сборка копируется в выходной путь.

  • Дополнительные файлы, которые имеют свойство "Копировать в выходной каталог". когда свойство установлено как "копировать всегда" или "копировать, если новый", файл копируется в выходной путь.

Проблема:

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

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

Solution1:

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

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

solution2:

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

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

Шаг 2:...

Удача

Ответ 4

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

Ответ 5

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

Ответ 6

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