Perché una fase post-build (xcopy) dovrebbe uscire occasionalmente con il codice 2 in una build TeamCity?


93

Alcuni progetti nella soluzione del mio cliente hanno un evento di post-compilazione: xcopyl'output di compilazione in una cartella specifica. Funziona bene quando si costruisce localmente. Tuttavia, in TeamCity, occasionalmente ottengo

xcopy [...] è terminato con il codice 2

Se uso regolare copy, esce con il codice 1. Mi aspetto che questo abbia qualcosa a che fare con i blocchi dei file, sebbene i file specifici che vengono copiati non siano gli stessi, quindi forse si limita a bloccare la directory di destinazione condivisa. Di solito /ynon chiedo di sovrascrivere i file.

Perché questo fallisce in TeamCity ma non localmente?


Ho avuto problemi simili, ma erano correlati alla copia simultanea dello stesso file in parallelo. Potresti ricontrollare che nessun file venga copiato due volte?
Ignacio Soler Garcia

4
Il codice di uscita 2 significa The user pressed CTRL+C to terminate xcopy. Hehe.
Hans Passant

@SoMoS Sì, i file copiati sono decisamente distinti.
Tim Iles

@HansPassant Non so perché teamcity vorrebbe premere CTRL + C su di me! :(
Tim Iles

5
Sì, nemmeno io. L'altra convenzione comune è che il codice di uscita è uguale all'ultimo errore o eccezione di Windows. Errore 2 significa "file non trovato". Il che ovviamente ha molto più senso.
Hans Passant

Risposte:


146

Anche se fornisci lo /Yswitch con xcopy, riceverai comunque un errore quando xcopy non sa se l'oggetto che stai copiando è un file o una directory. Questo errore apparirà come "uscito con codice 2". Quando esegui lo stesso xcopy al prompt dei comandi, vedrai che xcopy richiede una risposta di file o directory.

Per risolvere questo problema con una build automatizzata, puoi echeggiare una risposta predefinita con una pipe.

Per dire che la cosa che stai copiando è un file, fai eco in F:

echo F|xcopy /y ...

Per dire che la cosa che stai copiando è una directory, fai eco in D:

echo D|xcopy /y ...

A volte quanto sopra può essere risolto semplicemente usando un comando di copia invece di xcopy:

copy /y ...

Tuttavia, se sono presenti directory inesistenti che portano alla destinazione del file finale, si verificherà un "uscita con codice 1".

Ricorda: usa lo /Cswitch e xcopy con cautela.


Grazie @Metro Smurf. Non posso verificare se questo avrebbe risolto il mio problema, ma quello che dici sembra intelligente, quindi l'ho contrassegnato come risposta. Saluti!
Tim Iles

Mi sono imbattuto nello stesso identico problema e alla fine ho finito con il piping nella risposta. Si spera che questo aiuterà qualcun altro a lungo termine.
Metro Smurf

1
"Questo non funziona con le versioni localizzate di Windows, dove le parole del prompt potrebbero essere diverse. Un trucco alternativo è aggiungere un asterisco" "alla fine della destinazione, quindi xcopy non richiederà File / Directory. - Govert Jan 28 alle 19:40 "Quindi, puoi fare la copia in questo modo senza echo D (che non è affidabile): XCOPY $ (ProjectDir) .. \ scripts * $ (TargetDir) scripts * / Y / R. Oppure fai la copia in questo modo senza echo F: XCOPY D: \ file.zip c: \ renamedFile.zip / Y / R
leetNightshade

@leetNightshade - *funzionerà anche con le directory? O è solo per i file?
Metro Smurf

@MetroSmurf Hm, sembra che la formattazione del mio esempio non sia riuscita, mancano i backslash (devo aver pensato che stavo cercando di sfuggire a un simbolo) e l'asterisco mancante. Ma sì, funziona con directory e file. Ecco il link alla risposta di Govert: stackoverflow.com/a/14022309/353094
leetNightshade

37

Ho corretto il codice di errore 2 aggiungendo \ alla fine del mio percorso, senza di esso, xcopy penserà che si tratta di un file anziché di una cartella.


3
Questo è tutto. Ha funzionato perfettamente su Windows 7, Visual Studio 2013. Grazie mille!
Charles

33

Se stai usando xcopy in un evento di post compilazione, usa l'opzione / Y oltre a / C.

/C           Continues copying even if errors occur.
/Y           Suppresses prompting to confirm you want to overwrite an existing file.

4
Così semplice! /Ysopprime il prompt! Perché è stato così difficile da trovare?
SouthShoreAK

3
/ Y sopprime il prompt di sovrascrittura, ma questo non è l'unico motivo per un codice 2. RTFM non ti dirà cosa li causa.
MSalters

2

La mia soluzione per questo problema consisteva nell'andare nella cartella bin di destinazione e assicurarsi che la sottocartella corretta esistesse lì. Dopo che la sottocartella è stata creata manualmente, il processo di compilazione è stato completato correttamente.


2

copyrisolto per me. xcopy with /c /ynon ha funzionato. Stavo ottenendo un'uscita 4 quindi sono andato con xcopy, ma ho scoperto che avevo bisogno di citazioni in giro ($TargetPath).

Il mio script:

if $(ConfigurationName) == Debug copy "$(TargetPath)" "$(SolutionDir)\Folder\bin\Debug\$(TargetFileName)"

2

Probabilmente stai usando TeamCity con git. In caso affermativo, controlla che le cartelle che desideri copiare siano presenti nel repository git. Di solito git aviod aggiunge cartelle di progetto vuote al repository, quindi xcopynon riesce a trovarlo e genera un errore.

È possibile aggiungere un file di testo vuoto alla cartella vuota, eseguire il commit e vedere la cartella visualizzata nel repository.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.