Pourquoi une étape post-build (xcopy) se ferme-t-elle occasionnellement avec le code 2 dans une build TeamCity?

93

Quelques projets de la solution de mon client ont un événement post-build: xcopyla sortie de build dans un dossier spécifique. Cela fonctionne bien lors de la construction localement. Cependant, TeamCity, je parfois obtenir

xcopy [...] sorti avec le code 2

Si j'utilise regular copy, il sort avec le code 1. Je pense que cela a quelque chose à voir avec les verrous de fichiers, bien que les fichiers spécifiques copiés ne soient pas les mêmes, donc peut-être juste un verrouillage sur le répertoire de destination partagé. J'utilise /ypour ne pas demander d'écrasement des fichiers.

Pourquoi cela échoue dans TeamCity mais pas localement?

Tim Iles
la source
J'ai eu des problèmes similaires mais liés à la copie simultanée du même fichier en parallèle. Pouvez-vous vérifier qu'aucun fichier n'est copié deux fois?
Ignacio Soler Garcia
4
Le code de sortie 2 signifie The user pressed CTRL+C to terminate xcopy. Hehe.
Hans Passant
@SoMoS Oui, les fichiers copiés sont définitivement distincts.
Tim Iles
@HansPassant Je ne sais pas pourquoi teamcity voudrait appuyer sur CTRL + C sur moi! :(
Tim Iles
5
Yah, moi non plus. L'autre convention courante est que le code de sortie est égal à la dernière erreur ou exception Windows. L'erreur 2 signifie "fichier non trouvé". Ce qui a bien sûr beaucoup plus de sens.
Hans Passant

Réponses:

147

Même si vous fournissez le /Ycommutateur avec xcopy, vous obtiendrez toujours une erreur lorsque xcopy ne sait pas si l'élément que vous copiez est un fichier ou un répertoire. Cette erreur apparaîtra comme "sortie avec le code 2". Lorsque vous exécutez le même xcopy à une invite de commande, vous verrez que xcopy demande une réponse de fichier ou de répertoire.

Pour résoudre ce problème avec une génération automatisée, vous pouvez faire écho dans une réponse prédéfinie avec un canal.

Pour dire que ce que vous copiez est un fichier, faites un écho dans F:

echo F|xcopy /y ...

Pour dire que la chose que vous copiez est un répertoire, faites écho dans D:

echo D|xcopy /y ...

Parfois, ce qui précède peut être résolu en utilisant simplement une commande de copie au lieu de xcopy:

copy /y ...

Cependant, s'il y a des répertoires inexistants menant à la destination finale du fichier, alors un "sorti avec le code 1" se produira.

N'oubliez pas: utilisez le /Ccommutateur et xcopy avec prudence.

Schtroumpf du métro
la source
Merci @Metro Schtroumpf. Je ne peux pas tester si cela aurait résolu mon problème, mais ce que vous dites semble intelligent, donc je l'ai marqué comme la réponse. À votre santé!
Tim Iles
Je rencontrais exactement le même problème et je me suis finalement retrouvé avec un tuyau dans la réponse. Espérons que cela aidera quelqu'un d'autre à long terme.
Metro Schtroumpf
1
"Cela ne fonctionne pas sous les versions localisées de Windows, où les mots d'invite peuvent être différents. Une autre astuce consiste à ajouter un astérisque " à la fin de la destination, puis xcopy ne demandera pas de fichier / répertoire. - Govert Jan 28 at 19:40 "Donc, vous pouvez faire la copie comme ceci sans echo D (qui n'est pas fiable): XCOPY $ (ProjectDir) .. \ scripts * $ (TargetDir) scripts * / Y / R. Ou faites la copie comme ceci sans écho F: XCOPY D: \ file.zip c: \ renamedFile.zip / Y / R
leetNightshade
@leetNightshade - *fonctionnera-t-il également avec les répertoires? Ou est-ce juste pour les fichiers?
Metro Schtroumpf
@MetroSmurf Hm, il semble que le formatage de mon exemple ait échoué, il manque des contre-obliques (je dois avoir pensé que j'essayais d'échapper à un symbole) et un astérisque manquant. Mais oui, cela fonctionne avec les répertoires et les fichiers. Voici le lien vers la réponse de Govert: stackoverflow.com/a/14022309/353094
leetNightshade
37

J'ai corrigé le code d'erreur 2 en ajoutant un \ à la fin de mon chemin, sans lui, xcopy pensera qu'il s'agit d'un fichier au lieu d'un dossier.

Benjiko99
la source
3
C'est tout. Fonctionne très bien sur Windows 7, Visual Studio 2013. Merci beaucoup!
Charles
33

Si vous utilisez xcopy dans un événement post build, utilisez le commutateur / Y en plus de / C.

/C           Continues copying even if errors occur.
/Y           Suppresses prompting to confirm you want to overwrite an existing file.
DavidS
la source
4
Si simple! /Ysupprime l'invite! Pourquoi était-ce si difficile à trouver?
SouthShoreAK
3
/ Y supprime l'invite d'écrasement, mais ce n'est pas la seule raison d'un code 2. RTFM ne vous dira pas ce qui les cause.
MSalters
2

Ma solution à ce problème était d'aller dans le dossier bin cible et de m'assurer que le sous-dossier approprié existe. Une fois ce sous-dossier créé manuellement, le processus de génération s'est terminé avec succès.

boomer57
la source
2

copyréparé pour moi. xcopy with /c /yn'a pas marché. J'avais une sortie 4, alors je suis allé avec xcopy, mais il s'est avéré que j'avais besoin de devis ($TargetPath).

Mon scénario:

if $(ConfigurationName) == Debug copy "$(TargetPath)" "$(SolutionDir)\Folder\bin\Debug\$(TargetFileName)"
Mat
la source
2

Vous utilisez probablement TeamCity avec git. Si oui, vérifiez que les dossiers que vous souhaitez copier existent dans le référentiel git. Habituellement, git évite d'ajouter des dossiers de projet vides au référentiel, il xcopyne parvient donc pas à le trouver et génère une erreur.

Vous pouvez ajouter un fichier texte vide dans un dossier vide, valider et voir le dossier apparaît dans le référentiel.

iliya
la source