This answer is based on experiments I ran under Windows 10. I doubt there are differences with earlier Windows versions that use cmd.exe, but it is possible.
Also note - This answer does not attempt to document the ERRORLEVEL result when an internal command encounters an error (except for a wee bit concerning DEL and ERASE)
Not only are there difference between commands, but a single command can behave differently depending on whether it was run from the command line, or within a batch script with a .bat
extension, or from within a batch script with a .cmd
extension.
The following set of commands never clear the ERRORLEVEL to 0 upon success, regardless of context, but instead preserve the prior ERRORLEVEL:
- BREAK
- CLS
- ECHO
- ENDLOCAL
- FOR : Obviously, commands in the DO clause may set the ERRORLEVEL, but a successful FOR with at least one iteration does not set the ERRORLEVEL to 0 on its own.
- GOTO
- IF : Obviously, commands executed by IF may set the ERRORLEVEL, but a successful IF does not set ERRORLEVEL to 0 on its own.
- KEYS
- PAUSE
- POPD
- RD
- REM
- RMDIR
- SHIFT
- START
- TITLE
The next set of commands always clear the ERRORLEVEL to 0 upon success, regardless of context:
- CD
- CHDIR
- COLOR
- COPY
- DATE
- DEL : Always clears ERRORLEVEL, even if the DEL fails (except when run without any file argument).
- DIR
- ERASE : Always clears ERRORLEVEL, even if ERASE fails. (except when run without any file argument).
- MD
- MKDIR
- MKLINK
- MOVE
- PUSHD
- REN
- RENAME
- SETLOCAL
- TIME
- TYPE
- VER
- VERIFY
- VOL
Then there are these commands that do not clear ERRORLEVEL upon success if issued from the command line or within a script with a .bat
extension, but do clear the ERRORLEVEL to 0 if issued from a script with a .cmd
extension. See https://mcmap.net/q/16007/-windows-batch-files-bat-vs-cmd and https://groups.google.com/forum/#!msg/microsoft.public.win2000.cmdprompt.admin/XHeUq8oe2wk/LIEViGNmkK0J for more info.
- ASSOC
- DPATH
- FTYPE
- PATH
- PROMPT
- SET
Lastly, there are these commands that do not fit neatly into any of the prior categories:
CALL : If a :routine or batch script is CALLed, then ERRORLEVEL is exclusively controlled by the CALLed script or :routine. But any other type of successful CALL to a command will always clear ERRORLEVEL to 0 if the CALLed command does not otherwise set it.
Example: call echo OK
.
EXIT : If used without /B
, then the cmd.exe session terminates and there is no more ERRORLEVEL, just the cmd.exe return code. Obviously EXIT /B 0
clears the ERRORLEVEL to 0, but EXIT /B
without a value preserves the prior ERRORLEVEL.
I believe that accounts for all internal commands, unless there is an undocumented command that I missed.