Error en MSBuild & TeamBuild - BuildInParallel debido a la violación del permiso de archivo MSB3021


Mantengo la compilación de una pieza de software bastante grande, que consiste en aproximadamente 350 proyectos csharp. Nuestro tiempo de compilación para una depuración construyó relojes en aproximadamente 17 minutos.

He estado buscando formas de mejorar el tiempo de compilación, y la propiedad BuildInParallel parecía intrigante. Especialmente porque tenemos un servidor de cuatro núcleos que hace nuestras compilaciones, realmente debería ser capaz de aprovechar la potencia de cálculo.

Pero por desgracia... Después de establecer la propiedad, modificar el archivo de configuración para el agente de compilación y su reinicio, la primera ejecución realmente se veía prometedora, mucho más rápido de lo normal, hasta el punto en que falló.

Después de mirar los registros de compilación, parece que la compilación falla cuando intenta copiar referencias marcadas como CopyLocal=true al directorio de salida. Si el proyecto C # A y el proyecto C # B se construyen en paralelo, y ambos hacen referencia a la misma dll de terceros, e intentan copiarlo al mismo tiempo, el segundo proceso para intentar copiar el archivo obtener una violación de acceso al archivo - el archivo está siendo utilizado por otro proceso.

¿Alguien experimentó esto y pudo obtener compilaciones multiproc trabajando en la compilación en equipo?


Aquí está uno de los fracasos, un poco difícil de averiguar qué otro proyecto se estaba construyendo al mismo tiempo.

He eliminado todas las cosas no relevantes:

54 > Objetivo "_CopyFilesMarkedCopyLocal" en el archivo "c:\WINDOWS\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets" de proyecto "d:\temp\PCM\1.3-Maint_CI\Sources\Modules\Core\Test\UnitTest\TestDIPS.Núcleo.Datos.Servidor.NUnit \ TestDIPS.Núcleo.Datos.Servidor.NUnit.csproj": 54 > Tarea " Copiar" Copiando archivo desde "..........\ Bin \ 3rdParty \ Oracle \ Oracle.DataAccess.dll" a "d:\temp\PCM\1.3-Maint_CI\Binaries\Debug\Oracle.DataAccess.DLL". Comando: 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): error MSB3021: No se puede copiar el archivo "..........\ Bin \ 3rdParty \ Oracle \ Oracle.DataAccess.dll" a "d:\temp\PCM\1.3-Maint_CI\Binaries\Debug\Oracle.DataAccess.DLL". El el proceso no puede acceder al archivo 'd:\temp\PCM\1.3-Maint_CI\Binaries\Debug\Oracle.DataAccess.dll' porque está siendo utilizado por otro proceso. Terminado la ejecución de la tarea "Copiar" FAILED FALLÓ. 54 > Objetivo de construcción hecho "_CopyFilesMarkedCopyLocal" en el proyecto "TestDIPS.Núcleo.Datos.Servidor.NUnit.csproj " FAILED FALLÓ.

Author: NullUserException, 2009-04-02

6 answers

Los objetivos predeterminados que se envían con MSBuild están diseñados para el comportamiento CopyLocal, que es en lo que se basa VS. CopyLocal es problemático cuando se está enviando a un solo directorio de salida.

Para poder construir realmente en paralelo, necesitará deshabilitar varios comportamientos específicos CopyLocal en Microsoft.*.Común.*.archivos de objetivos. He hablado con algunas personas en el equipo de MSBuild en el pasado, y esto es algo particularmente difícil de hacer. Incluso si lo hace en blanco-fuera de algunos de los Comportamiento CopiLocal, los accesores de prueba VS no se comportan bien con build in parallel.

Algunas de las cosas con las que puedes empezar:

  1. Deshabilite el comportamiento CopyLocal para las referencias estableciendo private a true.
  2. Deshabilita CopyLocal para archivos CopyToOutputPath al compilar Proyectos dependientes.
 15
Author: gokult,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-30 06:17:11

La tarea de copia de MS Build tiene una función indocumentada, al menos Google guarda silencio. If set variable de entorno de todo el sistema MSBUILDALWAYSRETRY=1 Esta tarea volverá a intentar copiar un archivo aunque obtenga la excepción de Acceso denegado durante la operación de copia

Ejemplo de salida

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.
 9
Author: Nick Kashtanov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-26 07:43:40

Tengo el mismo problema hace muchos meses.

Hay dos tipos de copia de archivos en archivos de proyecto VS C# (.archivos csproj):

  1. Asambleas referenciadas que tienen una propiedad "Copiar local". cuando la propiedad es True, el ensamblado se copia en la ruta de salida.

  2. Archivos adicionales que tienen una propiedad "Copiar al directorio de salida". cuando la propiedad se establece en "copiar siempre" o "copiar si es más reciente", el archivo se copia en la salida camino.

Problema:

A: Si dos o más proyectos se construyen simultáneamente, y dos de ellos intentan copiar el mismo archivo en el directorio de salida, es posible que se enfrenten a errores como "error MSB3021: No se puede copiar el archivo", "Se niega el acceso a la ruta", "El proceso no puede acceder al archivo", etc.

B: Si dos o más proyectos refrenan un proyecto común que tiene algunos elementos de tipo 2. En este caso, durante la construcción paralela de los proyectos, dos de ellos pueden intentar construir el objetivo" GetCopyToOutputDirectoryItems " del proyecto común al mismo tiempo. Así que usted puede otra vez frente a las excepciones anteriores.

Solución 1:

Fuerza el OutputPath de diferente .los archivos csproj no deben estar en la misma ruta

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

Solución 2:

Paso 1: La solución es establecer la propiedad de Elementos comunes (a False en el caso 1 y a "no copiar" en el caso 2) para todos menos uno de estos elementos comunes en sus proyectos. o quitarlos si es posible.

Para encontrar posibles errores, puede buscar las palabras "private" (para el caso 1) y "CopyToOutputDirectory" (para el caso 2) en files *.csproj

Paso 2: ...

Buena suerte

 8
Author: Shahyad Sharghi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-29 16:16:34

Parece que sus proyectos están configurados en el mismo directorio de salida. Si configura el Proyecto A y el Proyecto B para generar salida a diferentes directorios, esto resolvería este error.

 1
Author: Hamid Shahid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-23 10:49:44

Esto también puede ocurrir debido a que el archivo es de solo lectura. En esos casos (es decir, no los cubiertos por la mayor parte de las otras respuestas), hay soluciones adecuadas que varían dependiendo de si puede confiar en MSBuild 3.5 o posterior.

 1
Author: Ruben Bartelink,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-04 10:53:38

¿Qué compilador está utilizando? Por lo que sé, hasta VS2005 parallel build no funciona para múltiples proyectos. Es un problema conocido que MS sigue diciendo que solucionarán eventualmente, pero no tengo idea de si realmente lo resolvieron en VS2008.

 0
Author: Tal Pressman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-04-23 01:44:47