Por que uma etapa de pós-construção (xcopy) ocasionalmente sairia com o código 2 em uma construção TeamCity?

93

Alguns projetos na solução do meu cliente têm um evento pós-compilação: xcopya saída da compilação para uma pasta específica. Isso funciona bem ao construir localmente. No entanto, no TeamCity, ocasionalmente consigo

xcopy [...] saiu com o código 2

Se eu usar regular copy, ele sairá com o código 1. Espero que isso tenha algo a ver com bloqueios de arquivo, embora os arquivos específicos que estão sendo copiados não sejam os mesmos, talvez apenas bloqueando no diretório de destino compartilhado. Eu costumo /ynão solicitar a substituição de arquivos.

Por que isso falha no TeamCity, mas não localmente?

Tim Iles
fonte
Tive problemas semelhantes, mas relacionados a copiar simultaneamente o mesmo arquivo em paralelo. Você poderia verificar se nenhum arquivo foi copiado duas vezes?
Ignacio Soler Garcia,
4
Código de saída 2 significa The user pressed CTRL+C to terminate xcopy. Ele Ele.
Hans Passant de
@SoMoS Sim, os arquivos que estão sendo copiados são definitivamente diferentes.
Tim Iles de
@HansPassant Não sei por que o teamcity iria querer pressionar CTRL + C em mim! :(
Tim Iles,
5
Sim, eu também não. A outra convenção comum é que o código de saída é igual ao último erro ou exceção do Windows. Erro 2 significa "arquivo não encontrado". O que, claro, faz muito mais sentido.
Hans Passant de

Respostas:

146

Mesmo se você fornecer o /Yswitch com xcopy, ainda obterá um erro quando xcopy não souber se o que você está copiando é um arquivo ou um diretório. Este erro aparecerá como "saiu com o código 2". Ao executar o mesmo xcopy em um prompt de comando, você verá que o xcopy está solicitando uma resposta de arquivo ou diretório.

Para resolver esse problema com uma construção automatizada, você pode enviar uma resposta predefinida com um tubo.

Para dizer que o que você está copiando é um arquivo, faça eco em F:

echo F|xcopy /y ...

Para dizer que o que você está copiando é um diretório, faça eco em D:

echo D|xcopy /y ...

Às vezes, o acima pode ser resolvido simplesmente usando um comando de cópia em vez de xcopy:

copy /y ...

No entanto, se houver diretórios inexistentes que conduzam ao destino final do arquivo, ocorrerá uma "saída com o código 1".

Lembre-se: use o /Cswitch e o xcopy com cuidado.

Metro Smurf
fonte
Obrigado @Metro Smurf. Não posso testar se isso teria resolvido meu problema, mas o que você diz parece inteligente, por isso marquei como a resposta. Felicidades!
Tim Iles
Eu estava enfrentando exatamente o mesmo problema e, no final das contas, terminei com problemas na resposta. Esperançosamente, isso ajudará alguém no longo prazo.
Metro Smurf
1
"Isso não funciona em versões localizadas do Windows, onde as palavras do prompt podem ser diferentes. Um truque alternativo é adicionar um asterisco ' ' ao final do destino, então xcopy não solicitará Arquivo / Diretório. - Govert Jan 28 às 19:40 "Então, você pode fazer a cópia assim sem echo D (que não é confiável): XCOPY $ (ProjectDir) .. \ scripts * $ (TargetDir) scripts * / Y / R. Ou faça a cópia assim sem eco F: XCOPY D: \ file.zip c: \ renamedFile.zip / Y / R
leetNightshade
@leetNightshade - *funcionará com diretórios também? Ou isso é apenas para arquivos?
Metro Smurf
@MetroSmurf Hm, parece que a formatação do meu exemplo falhou, estão faltando barras invertidas (devo ter pensado que estava tentando escapar de um símbolo) e asterisco faltando. Mas sim, funciona com diretórios e arquivos. Aqui está o link para a resposta de Govert: stackoverflow.com/a/14022309/353094
leetNightshade
37

Corrigi o código de erro 2 adicionando um \ no final do meu caminho, sem ele, o xcopy pensará que é um arquivo em vez de uma pasta.

Benjiko99
fonte
3
É isso aí. Funcionou muito bem no Windows 7, Visual Studio 2013. Muito obrigado!
Charles
33

Se você estiver usando xcopy em um evento pós-compilação, use a opção / Y além de / C.

/C           Continues copying even if errors occur.
/Y           Suppresses prompting to confirm you want to overwrite an existing file.
DavidS
fonte
4
Tão simples! /Ysuprime o prompt! Por que isso foi tão difícil de encontrar?
SouthShoreAK
3
/ Y suprime o prompt de substituição, mas esse não é o único motivo para um código 2. O RTFM não dirá a você o que os causa.
MSalters
2

Minha correção para esse problema foi ir para a pasta bin de destino e garantir que a subpasta adequada existe lá. Depois que essa subpasta foi criada manualmente, o processo de construção foi concluído com êxito.

boomer57
fonte
2

copyconsertou para mim. xcopy with /c /ynão funcionou. Eu estava pegando uma saída 4, então aceitei xcopy, mas descobri que precisava de orçamentos ($TargetPath).

Meu roteiro:

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

Provavelmente você está usando TeamCity com git. Se sim, verifique se as pastas que você deseja copiar existem no repositório git. Normalmente git aviod adicionando pastas de projeto vazias ao repositório, então xcopyfalha em encontrá-lo e gera um erro.

Você pode adicionar algum arquivo de texto vazio a uma pasta vazia, confirmar e ver a pasta aparecer no repositório.

iliya
fonte