What is the easiest way to reset ERRORLEVEL to zero?

I have a post-build event that runs some commands for a c# project. The last command would sometimes cause the ERRORLEVEL value not equals to zero and then the build fails.

I want to append an extra line of command to always set the ERRORLEVEL value to zero. What is the most convenient way to do that?

90775 次浏览

Seems to do the trick:

ver > nul

Not everything works, and it is not clear why. For example, the following do not:

echo. > nul
cls > nul

I found that "exit 0" looks like a good way to deal with this problem.

Usage Example:

NET STOP UnderDevService /Y

exit 0

if the UnderDevService service is not started.

if you use exit /b 0 you can return an errorlevel 0 from within a child batch script without also exiting the parent.

In a pre- or post-build event, if the return code of an executable is greater than zero, and the call to the executable is not the last line of the pre- or post-build event, a quick way to mute it and avoid triggering a check for a non-zero errorlevel is to follow the failing line with a line that explicitly returns zero:

cmd /c "exit /b 0"

This is essentially a generic combination of the previously-mentioned solutions that will work with more than just the last line of a pre- or post-build event.

Add >nul after each command that's likely to fail - this seems to prevent the build from failing.

You can still check the result of the command by examining %errorlevel%.

For example:

findstr "foo" c:\temp.txt>nul & if %errorlevel% EQU 0 (echo found it) else (echo didn't find it)

I use VERIFY or VERIFY > nul

I always just used;

set ERRORLEVEL=0

I've been using it for donkey's years.

I'm using this:

ping localhost -n 1 >null

If this is a snippet like "Post-build Event" etc., then you'll be fine appending:

(...) || ver > nul

at the end of the last command.

Alternatively

cmd /c "exit /b 0"

is very clean and non-idiomatic -- a reader who knows Windows shell will know what's going on, and what was your intent.

However, if you're in a batch script, you may want to use subrotines, which are a lightweight equivalent of the "child batch script" from akf's answer.

Have a subroutine:

:reset_error
exit /b 0

and then just

call :reset_error

wherever you need it.

Here's a complete example:

@echo off
rem *** main ***


call :raise_error
echo After :raise_error ERRORLEVEL = %ERRORLEVEL%


call :empty
echo After :empty ERRORLEVEL = %ERRORLEVEL%


call :reset_error
echo After :reset_error ERRORLEVEL = %ERRORLEVEL%


:: this is needed at the end of the main body of the script
goto:eof


rem *** subroutines ***


:empty
goto:eof


:raise_error
exit /b 1


:reset_error
exit /b 0

Which outputs:

After :raise_error ERRORLEVEL = 1
After :empty ERRORLEVEL = 1
After :reset_error ERRORLEVEL = 0

As you see - just calling and returning via goto:eof is not enough.

I personally use this:

cd .

Works even in unix shell.

But, this one might be a bit faster:

type nul>nul

Because Process Monitor shows QueryDirectory calls on cd .

PS: cd . has another nice side effect in the unix shell. It does restore recreated working directory in the terminal if it has been opened before the erase.

Update:

And that is a bit more faster:

call;

https://www.dostips.com/forum/viewtopic.php?t=5542

Here are some other ways to reset the ErrorLevel state, which even work in MS-DOS (at least for version 6.22):

more < nul > nul


rem // The `> nul` part can be omitted in Windows but is needed in MS-DOS to avoid a line-break to be returned:
sort < nul > nul

The following methods work in MS-DOS only:

command /? > nul


fc nul nul > nul


keyb > nul

For the sake of completeness, this sets the ErrorLevel state to 1, valid for both Windows and MS-DOS:

< nul find ""

After reviewing all of the other answers, I decided to find which way was the most efficient for resetting the ERRORLEVEL. I made a quick script that recorded the time to execute each of these:

"cmd /c "exit /b 0"", "cd .", "ver", "type nul", and "VERIFY"

here is the output:

cmd /v:on /c set ^"q=^"^" & timeit.cmd "cmd /c ^!q^!exit /b 0^!q^!" "cd ." "ver" "type nul" "VERIFY"

cmd /c "exit /b 0" took 0:0:0.02 (0.02s total)

cd . took 0:0:0.00 (0.00s total)

Microsoft Windows [Version 10.0.18362.836]

ver took 0:0:0.00 (0.00s total)

type nul took 0:0:0.00 (0.00s total)

VERIFY is off. VERIFY took 0:0:0.00 (0.00s total)


This took 0:0:0.06 (0.06s total)

after reviewing with Measure-Command {command} in Powershell, I found that it only really accepted cd . and cmd /c "exit /b 0" --am I doing something wrong?

I'd recommend either cd . or type nul since neither have a footprint on the output of the console, nor are they slow in any measure.

yeah I'm pretty bored

The following works in modern Windows (NT-based) systems that feature cmd.exe:

rem /* This clears `ErrorLevel`; the SPACE can actually be replaced by an
rem    arbitrary sequence of SPACE, TAB, `,`, `;`, `=`, NBSP, VTAB, FF: */
(call )

The SPACE (or more precisely, an arbitrary sequence of one or more standard token separators, which are SPACE (code 0x20), 0x091 (code 0x09), ,, ;, =, 0x092 (code 0xFF), 0x093 (code 0x0B) and 0x094 (code 0x0C)) is mandatory; if you omit it the ErrorLevel becomes set instead:

rem // This sets `ErrorLevel` to `1`:
(call)

There is a nice thread on DosTips.com where this technique came up.


Here is an alternative method, but which accesses the file system and might therefore be a bit slower:

dir > nul


rem /* Perhaps this is a little faster as a specific file is given rather
rem    than just the current directory (`.` implicitly) like above: */
dir /B "%ComSpec%" > nul