2009-04-01 2 views
26

Mantengo la creazione di un software abbastanza grande, costituito da circa 350 progetti csharp. Il nostro tempo di compilazione per un debug costruito orologi in circa 17 minuti.MSBuild & TeamBuild - Errore BuildInParallel a causa della violazione dei permessi del file MSB3021

Ho cercato modi per migliorare i tempi di costruzione e la proprietà BuildInParallel sembrava interessante. Soprattutto perché abbiamo un server quad-core che fa le nostre build, dovrebbe essere davvero in grado di sfruttare la potenza di calcolo.

Ma ahimè ... Dopo aver impostato la proprietà, modificato il file di configurazione per l'agente di build e riavviarlo, la prima esecuzione sembrava davvero promettente, molto più veloce del normale, fino al punto in cui non era riuscita.

Dopo aver esaminato i log di build, sembra che la compilazione non riesca quando tenta di copiare i riferimenti contrassegnati come CopyLocal = true nella directory ouput. Se il progetto C# A e il progetto C# sono costruiti in parallelo e entrambi fanno riferimento alla stessa DLL di terze parti e tenta di copiarlo nello stesso momento, il secondo processo per tentare di copiare il file otterrà una violazione di accesso al file - il file è utilizzato da un altro processo.

Chiunque ha provato questo ed è stato in grado di ottenere build multi-proc lavorando su Team Build?


Ecco uno dei fallimenti, un po 'difficile da capire quale altro progetto è stato costruito allo stesso tempo.

Ho rimosso tutto il materiale non rilevante:

54> Target "_CopyFilesMarkedCopyLocal" nel file "C: \ WINDOWS \ Microsoft.NET \ Framework \ v3.5 \ Microsoft.Common.targets " dal progetto " d: \ temp \ PCM \ 1.3-Maint_CI \ Sources \ Modules \ Core \ Test \ UnitTest \ TestDIPS.Core.Data.Server.NUnit \ TestDIPS.Core.Data.Server.NUnit.csproj ": 54> Attività "Copia" Copia di file da ".......... \ Bin \ 3rdParty \ Oracle \ Oracle.DataAccess.dll" a "d: \ temp \ PCM \ 1.3-Maint_CI \ Binaries \ Debug \ Oracle.DataAccess.dll". Comando: copia/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): errore MSB3021: Impossibile copiare il file " ....... ... \ Bin \ 3rdParty \ Oracle \ Oracle.DataAccess.dll "a " d: \ temp \ PCM \ 1.3-Maint_CI \ Binaries \ Debug \ Oracle.DataAccess.dll ". Il processo non può accedere al file 'd: \ temp \ PCM \ 1.3-Maint_CI \ Binaries \ Debug \ Oracle.DataAccess.dll' perché è utilizzato da un altro processo. Compito eseguito "Copia" - NON RIUSCITO. 54> Fine edificio target "_CopyFilesMarkedCopyLocal" nel progetto "TestDIPS.Core.Data.Server.NUnit.csproj" - FAILED.

risposta

15

I target predefiniti forniti con MSBuild sono progettati per il comportamento CopyLocal, che è ciò su cui si basa VS. CopyLocal è problematico quando si esegue l'output in una singola directory di output.

Per essere veramente in grado di creare in parallelo, è necessario disabilitare diversi comportamenti specifici di CopyLocal nei file Microsoft. *. Common. *. Target. Ho parlato con alcune persone del team di MSBuild in passato, e questa è una cosa particolarmente difficile da fare. Anche se si eliminano alcuni comportamenti di CopyLocal, gli accessori di test VS non si comportano bene con build in parallelo.

Alcune delle cose che si può iniziare con:

  1. comportamento Disabilita CopyLocal i riferimenti impostando privato a vero.
  2. Disabilitare CopyLocal per i file CopyToOutputPath durante la creazione di progetti dipendenti.
+0

Ci scusiamo per la risposta tardiva, ma grazie mille per la risposta chiarificatrice. La tua risposta è in linea con le mie ultime scoperte, ho avuto problemi con i test di accesso. Ho scoperto che avrei dovuto bandire i metodi di verifica o modificare il file dei target, che è qualcosa che non vogliamo fare. Si spera che venga risolto in Team Build 2010/.Net 4.0 –

0

Quale compilatore stai utilizzando? Per quanto ne so, fino a quando la build parallela VS2005 non funziona per più progetti. È un problema noto che MS continua a dire che alla fine si risolveranno, ma non ho idea se abbiano effettivamente risolto il problema in VS2008.

+0

Siamo pienamente il TFS2008, entrambi i client e buildserver –

1

Sembra che i progetti siano configurati sulla stessa directory di output. Se si configura Progetto A e Progetto B per l'output in diverse directory, questo risolverebbe questo errore.

+0

Sì, ma questo è il comportamento predefinito per TeamBuild e non voglio cambiarlo se non c'è altro modo per aggirarlo. –

8

Ho lo stesso problema molti mesi fa.

Ci sono due tipi di copia di file in file di progetto # VS C (.csproj file):

  1. Assemblee fatto riferimento alla quale ha una proprietà "copia locale". quando la proprietà è True, l'assembly viene copiato nel percorso di output.

  2. Altri file con una proprietà "Copia nella directory di output". quando la proprietà è impostata su "copia sempre" o "copia se più recente" il file viene copiato nel percorso di output.

problema:

A: Se due o più progetti sono costruiti in concomitanza, e due di loro cerca di copiare lo stesso file nella directory di output, è possibile che di fronte alle errori come "Errore MSB3021: Impossibile per copiare il file "," Accesso al percorso negato "," Il processo non può accedere al file ", ecc.

B: Se due o più progetti rifrange un progetto comune che ha alcuni elementi di tipo 2. In questo caso durante la generazione parallela dei progetti, due di essi potrebbero provare a creare contemporaneamente l'obiettivo "GetCopyToOutputDirectoryItems" del progetto comune. Quindi potresti nuovamente affrontare le eccezioni di cui sopra.

Soluzione1:

forza l'OutputPath di diversi Csproj non i file di essere in tha stesso percorso

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

Solution2:

Step1: La soluzione è quella di impostare la proprietà di Elementi comuni (a False nel caso 1 e a "non copiare" nel caso 2) per tutti tranne uno di questi elementi comuni nei progetti. o rimuoverli se è possibile.

Al fine di trovare potenziali errori, è possibile cercare le parole "privata" (per caso 1) e "CopyToOutputDirectory" (per caso 2) nei file * Csproj

Step2: ...

Good Luck

1

Questo può verificarsi anche a causa del file in fase di sola lettura. In quei casi (vale a dire, non quelli coperti dalla maggior parte delle altre risposte), there are appropriate workarounds which vary depending on whether you're able to rely on MSBuild 3.5 or later.

+0

Anche se ciò potrebbe teoricamente rispondere alla domanda, [sarebbe preferibile] (http://meta.stackexchange.com/q/8259) includere le parti essenziali della risposta qui e fornire il link per riferimento. Sto cancellando questo per ora, se aggiungi i dettagli rilevanti segnalalo per l'attenzione del moderatore. – NullUserException

9

L'attività di copia di MS Build ha una funzionalità non documentata, almeno Google mantiene il silenzio. Se l'ambiente a livello di sistema impostato MSBUILDALWAYSRETRY variabile = 1 Questo compito riproverà per copiare un file anche ottiene eccezione Accesso negato durante un'operazione di copia

Esempio di uscita

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. 
+2

https://github.com/Microsoft/msbuild/blob/master/src/XMakeTasks/Copy.cs –

+0

Il collegamento è rotto –