Dlaczego krok po kompilacji (xcopy) czasami kończy się z kodem 2 w kompilacji TeamCity?

93

Kilka projektów w rozwiązaniu mojego klienta ma zdarzenie po kompilacji: xcopydane wyjściowe kompilacji do określonego folderu. Działa to dobrze, gdy budujesz lokalnie. Jednak w TeamCity czasami dostaję

xcopy [...] zakończył działanie z kodem 2

Jeśli używam zwykłego copy, kończy się z kodem 1. Spodziewam się, że ma to coś wspólnego z blokadami plików, chociaż kopiowane pliki nie są takie same, więc może po prostu blokowanie we współdzielonym katalogu docelowym. Używam, /yaby nie pytać o nadpisywanie plików.

Dlaczego to zawodzi w TeamCity, ale nie lokalnie?

Tim Iles
źródło
Miałem podobne problemy, ale związane z jednoczesnym kopiowaniem tego samego pliku równolegle. Czy możesz dwukrotnie sprawdzić, czy żaden plik nie jest kopiowany dwukrotnie?
Ignacio Soler Garcia
4
Kod wyjścia 2 oznacza The user pressed CTRL+C to terminate xcopy. Hehe.
Hans Passant
@SoMoS Tak, kopiowane pliki są zdecydowanie różne.
Tim Iles,
@HansPassant Nie wiem, dlaczego teamcity chciałoby naciskać na mnie CTRL + C! :(
Tim Iles,
5
Tak, ja też nie. Inną powszechną konwencją jest to, że kod zakończenia jest równy ostatniemu błędowi lub wyjątkowi systemu Windows. Błąd 2 oznacza „nie znaleziono pliku”. Co oczywiście ma dużo więcej sensu.
Hans Passant

Odpowiedzi:

147

Nawet jeśli udostępnisz /Yprzełącznik xcopy, nadal będziesz otrzymywać błąd, gdy xcopy nie będzie wiedział, czy kopiowana rzecz to plik czy katalog. Ten błąd pojawi się jako „wyjście z kodem 2”. Po uruchomieniu tego samego xcopy w wierszu polecenia zobaczysz, że xcopy prosi o odpowiedź pliku lub katalogu.

Aby rozwiązać ten problem za pomocą automatycznej kompilacji, możesz powtórzyć wstępnie zdefiniowaną odpowiedź za pomocą potoku.

Aby powiedzieć, że kopiowana rzecz to plik, powtórz F:

echo F|xcopy /y ...

Aby powiedzieć, że kopiowana rzecz to katalog, powtórz w D:

echo D|xcopy /y ...

Czasami powyższy problem można rozwiązać, po prostu używając polecenia kopiowania zamiast xcopy:

copy /y ...

Jeśli jednak istnieją nieistniejące katalogi prowadzące do ostatecznego miejsca docelowego pliku, nastąpi „wyjście z kodem 1”.

Pamiętaj: /Costrożnie używaj przełącznika i xcopy.

Metro Smurf
źródło
Dzięki @Metro Smurf. Nie mogę sprawdzić, czy to rozwiązałoby mój problem, ale to, co mówisz, brzmi sprytnie, więc oznaczyłem to jako odpowiedź. Twoje zdrowie!
Tim Iles
Miałem dokładnie ten sam problem i ostatecznie skończyło się na tym, że w odpowiedzi pojawiły się przewody. Mam nadzieję, że na dłuższą metę pomoże to komuś innemu.
Metro Smurf
1
„To nie działa w zlokalizowanych wersjach systemu Windows, w których słowa zachęty mogą być inne. Alternatywną sztuczką jest dodanie gwiazdki„ ”na końcu miejsca docelowego, a następnie xcopy nie monituje o plik / katalog. - Govert Jan 28 o 19:40 "Więc możesz wykonać taką kopię bez echa D (co nie jest wiarygodne): XCOPY $ (ProjectDir) .. \ scripts * $ (TargetDir) scripts * / Y / R. Lub wykonaj kopię w ten sposób bez echa F: XCOPY D: \ file.zip c: \ renamedFile.zip / Y / R
leetNightshade
@leetNightshade - czy będzie *działać również z katalogami? Czy to tylko dla plików?
Metro Smurf
@MetroSmurf Hm, wygląda na to, że formatowanie mojego przykładu nie powiodło się, brakuje odwrotnych ukośników (musiałem pomyśleć, że próbuję uciec przed symbolem) i brakuje gwiazdki. Ale tak, działa z katalogami i plikami. Oto link do odpowiedzi Goverta: stackoverflow.com/a/14022309/353094
leetNightshade
37

Naprawiłem kod błędu 2, dodając \ na końcu mojej ścieżki, bez niego xcopy pomyśli, że jest to plik zamiast folderu.

Tomáš Beňo
źródło
3
Otóż ​​to. Działało dobrze na Windows 7, Visual Studio 2013. Wielkie dzięki!
Charles
33

Jeśli używasz xcopy w zdarzeniu po kompilacji, użyj przełącznika / Y oprócz / C.

/C           Continues copying even if errors occur.
/Y           Suppresses prompting to confirm you want to overwrite an existing file.
DavidS
źródło
4
Tak prosty! /Ypomija monit! Dlaczego było to tak trudne do znalezienia?
SouthShoreAK
3
/ Y pomija monit o nadpisanie, ale nie jest to jedyny powód kodu 2. RTFM nie powie ci, co je powoduje.
MSalters
2

Moją poprawką dla tego problemu było przejście do docelowego folderu bin i upewnienie się, że istnieje tam odpowiedni podfolder. Po ręcznym utworzeniu tego podfolderu proces kompilacji zakończył się pomyślnie.

boomer57
źródło
2

copynaprawił to dla mnie. xcopy with /c /ynie działał. Dostałem wyjście 4, więc poszedłem z xcopy, ale okazało się, że potrzebowałem cytatów ($TargetPath).

Mój skrypt:

if $(ConfigurationName) == Debug copy "$(TargetPath)" "$(SolutionDir)\Folder\bin\Debug\$(TargetFileName)"
Matt
źródło
2

Prawdopodobnie używasz TeamCity z git. Jeśli tak, sprawdź, czy foldery, które chcesz skopiować, istnieją w repozytorium git. Zwykle git aviod dodaje puste foldery projektu do repozytorium, więc xcopynie znajduje go i generuje błąd.

Możesz dodać jakiś pusty plik tekstowy do pustego folderu, zatwierdzić i zobaczyć, jak folder pojawia się w repozytorium.

iliya
źródło