5
2
Microsoft documentation states that the xcopy
exit codes are
Exit code Description
0 Files were copied without error.
1 No files were found to copy.
2 The user pressed CTRL+C to terminate xcopy.
4 Initialization error occurred.
There is not enough memory or disk space,
or you entered an invalid drive name
or invalid syntax on the command line.
5 Disk write error occurred.
I'm running a Windows 10 64bit system (spanish locale), and I've tried everything I could think of to get an errorlevel 1
from xcopy
, but I've not been able. And by everything I mean the only thing I did not test was /N
with long file names in a source where short names are not enabled (in my environment I can not test it). The usual suspects non matching wildcards, non present file names, empty folders, /D
, /EXCLUDE
, /A
, /M
, /U
, ... were tested.
I though it should be easy (not files found?, easy), but I was wrong, it was not, so I debugged xcopy.exe
and this is what I saw:
xcopy
internally uses a method calledDisplayMessageAndExit(messageID, WSTRING, exitCode)
to, well, display a message and exit. It also uses severalexit
calls to leave the program in some cases (ex. Ctrl-C)I have not found any
exit
call that could use a value of1
From the list of calls made to
DisplayMessageAndExit
, none of them pass/receive a value of1
as exit code.From the list of calls made to
DisplayMessageAndExit
only one of them use the MessageID0x5622
(in my install the resources associated are inC:\Windows\System32\es-ES\ulib.dll.mui
, it is locale dependent), that isNo se encuentra el archivo: %1
(File not found - %1
), and the exit code used in the call is4
Maybe there is a way in which xcopy
is able to generate the 1
exit code, but I don't know how.
So the question is: Is there a way to get errorlevel 1
exit code from xcopy
? What am I missing?
I would expect it if you use
/d
and no files are newer. – AFH – 2017-02-18T11:58:06.487@AFH Nope.
/d
doesn't do it. – DavidPostill – 2017-02-18T13:04:18.767@DavidPostill - Sorry, I didn't have time to check. I did say I would expect it, and I feel it should. – AFH – 2017-02-18T13:07:16.573
@AFH You are right it should (it returns
0
). I triedxcopy foo bar
wherefoo
doesn't exist and that didn't do it either (it returns4
). – DavidPostill – 2017-02-18T13:24:45.927@DavidPostill, As I see it there are two options: it is impossible or it is something so obvious I'm not seeing it. But all that I though as obvious did not work. – MC ND – 2017-02-18T13:35:06.397
@DavidPostill - The only other possibilities I can think of which should return 1 are copying an empty directory or using a file mask has no matches. – AFH – 2017-02-18T21:11:46.140
@MCND - Like you, I've tried everything I can think of, without finding anything which returns 1. It very much looks like a long-standing bug. The best you can do is
xcopy ... >%temp%\xcopy.tmp
; if the return code is 0, usefindstr /l "0 File(s) copied"<%temp%\xcopy.tmp
to check for no files copied. Don't be tempted to pipe to anything: eg piping totee
will give the return code set bytee
, not fromxcopy
. – AFH – 2017-02-19T18:52:17.830@AFH, After testing I was 80% sure it is a bug. After debugging
xcopy
I was 99.9% sure it is a bug, but I could have overlooked something that someone else knows. Yes, I know how to handle the0 File(s)
, and the pipe behaviour but in this case I'm only interested on the exit code behaviour. Anyway, thank you for your testing. – MC ND – 2017-02-19T19:37:32.3472I guess that they in Microsoft know it. There is a sample
COPYIT.BAT
at the provided link to performxcopy
operations and use the batchif
command to process the exit code if an error occurs. The batch does not care abouterrorlevel 1
at all and processes only errolevels 4, 2 and 0 (it's not a bug, it's a feature?) – JosefZ – 2017-04-06T07:20:21.587@JosefZ, Thank you, I missed the batch file (rendering in one line does not help). It seems that who write it don't really know how
errorlevel
works.if errorlevel 0
is always true for any non negative errorlevel value, andxcopy
doesn't document negative values. It seems the intention is to use a fallthrough into the following label to handle theerrorlevel 1
case, but, as said, the code is wrong. – MC ND – 2017-04-06T08:15:05.327I guess that
if errorlevel 0 goto exit
is intended to skip following:lowmemory
label (please note theif errorlevel 4 goto lowmemory
. Errorlevel is tested properly in descending order. Missing check ofif errorlevel 1
is more interesting thing for me from view of your question. – JosefZ – 2017-04-06T10:26:03.1932@JosefZ, to skip
:lowmemory
you only need agoto
, not aif errorlevel 0
that in this scenario is always true. Why to use anif
? It is just my opinion, but for me it seems a (wrong) fallthrough, as in Cswitch
statement. Of course I don't know "why" and I could be wrong (again). In any case, yes, your point creates a suspicious omission in their code. – MC ND – 2017-04-06T10:48:57.980Tried a wildcard expand that expanded to nothing; nope that error code is 0! – Joshua – 2018-12-05T18:36:11.680