89

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?

aschipfl
  • 33,626
  • 12
  • 54
  • 99
user95319
  • 1,213
  • 1
  • 8
  • 12
  • 1
    The build doesn't really fail, only the IDE does look like it. – Dykam Jul 11 '09 at 14:02
  • 12
    I realize this is a pretty old post... I had success in resetting the errorlevel to 0 by issuing the command "type nul" after the last command. Just felt it might be of use. – Arun Aug 20 '13 at 22:54

14 Answers14

76

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

beppe9000
  • 1,056
  • 1
  • 13
  • 28
akf
  • 38,619
  • 8
  • 86
  • 96
  • 7
    Out of all the proposed solutions, this is probably be the best one. I'm going to toss this line into a *resetErrorlevel.bat* script. All in all, the fact that one has to go to such lengths to do something as trivial as clearing a script's error level is yet more proof that the inventor of Windows batch programming should be hunted down and punished harshly. ;) – antred Mar 23 '15 at 15:29
59

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
Jason Kresowaty
  • 16,105
  • 9
  • 57
  • 84
  • 14
    I think the reason of why "echo" and "cls" don't work is because they are the shell built-in commands, not real programs. – user95319 Jul 11 '09 at 13:43
  • 3
    I'll give you that, but where is ver.exe? – Jason Kresowaty Jul 11 '09 at 15:28
  • I can't find "ver.exe" or "ver.com" either. I don't know how to explain that. – user95319 Jul 12 '09 at 13:29
  • 1
    At batch command line, "ver" returns the MS windows version, eg "Microsoft Windows [Version 6.1.7601]". – AnneTheAgile May 29 '13 at 16:40
  • 6
    if you run help in command shell, you will see ver is also a built in command – Baiyan Huang Jun 03 '14 at 01:49
  • 2
    @BaiyanHuang - I'm nearly positive `"ver"` is an internal command, but how can you tell from `"help"` ? Many of the commands listed in `"help"` are "external" commands like: `Find.exe`, `Findstr.exe`, `Help.exe`, `Subst.exe`, `Wmic.exe`, `Xcopy.exe`, ... – Kevin Fegan Jul 09 '16 at 07:23
34

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.

twasbrillig
  • 17,084
  • 9
  • 43
  • 67
Jeffrey Wilges
  • 1,170
  • 9
  • 9
  • thanks, this worked for me. the easier sounding suggestion of 'exit 0' above doesn't cut it as I wish to continue doing stuff after resetting the errorlevel, not exit – madoki Nov 30 '11 at 09:34
  • 4
    even more fancy: you can use ` || cmd /c "exit /b 0"` as a one liner. – Alyssa Haroldsen Jul 12 '13 at 21:40
  • I like this method for ***setting*** an arbitrary errorlevel like: `cmd /c "exit /b 9009"`, but it seems a bit overkill for setting it to 0. Wouldn't `ver > nul` (an internal command), work just as well with less overhead than loading another copy of the command shell with `cmd /c "exit /b 0"` ? – Kevin Fegan Jul 09 '16 at 06:18
  • 2
    The `/b` is not needed so `cmd /c “exit 0”` works fine too. – Ross Smith II Nov 14 '18 at 15:03
  • I like this one does the job. Thanks. One funny thing im tracing some file and my error level kept changing to 1, finally i found that prompting the user like (set /p id="enter id") changes the errorlevel to 1! ... I had filled the b – A Khudairy Oct 19 '20 at 12:39
23

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;

Any windows command to find if a file is in use or not ? :
https://www.dostips.com/forum/viewtopic.php?t=5542

Andry
  • 2,273
  • 29
  • 28
18

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.

NET3
  • 1,520
  • 1
  • 16
  • 25
user95319
  • 1,213
  • 1
  • 8
  • 12
  • 14
    not if you also want to run that batch file from the command line, as exit 0 will close the window. cmd /c "exit /b 0" as suggested below is much more bening – madoki Nov 30 '11 at 09:33
9

I use VERIFY or VERIFY > nul

ixe013
  • 9,559
  • 3
  • 46
  • 77
6

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.

Tomasz Gandor
  • 8,235
  • 2
  • 60
  • 55
4

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), TAB (code 0x09), ,, ;, =, NBSP (code 0xFF), VTAB (code 0x0B) and FF (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
aschipfl
  • 33,626
  • 12
  • 54
  • 99
2

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 ""
aschipfl
  • 33,626
  • 12
  • 54
  • 99
1

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

alexlyee
  • 11
  • 2
  • Yes, `cmd /C exit [/B] 0` should be the slowest since a new `cmd.exe` instance is opened and closed; the others are all internal commands, so there is no file system access to find executable files… – aschipfl Oct 21 '20 at 17:47
0

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)
Cosmin
  • 21,216
  • 5
  • 45
  • 60
Chiefy
  • 1
  • 2
    This won't work -- the shell evaluates the entire command line at once, so %errorlevel% will be substituted before the "findstr" command is executed. Use "if errorlevel 1" instead to test for a non-zero errorlevel. – UweBaemayr Mar 03 '16 at 15:29
  • 2
    Probably your CI server fails builds if it for example finds the string "error" in the standard output / standard error. You're not resetting the status. You're just silencing the command. For a deeper silence use >nul 2>nul – Tomasz Gandor Oct 11 '16 at 21:36
-1

Tried all solutions above - nothing worked. But found this solution that works for me inside the batch file:

set /A errorlevel=0

(the /A switch defines the supplied value as a numerical expression)

Yumb
  • 1
  • 5
  • 2
    DO NOT do this! It overrides the "magic" system variable, which then doesn't work correctly anymore until you "unset" this variable. – Stephan Mar 08 '23 at 18:54
-3

I'm using this:

ping localhost -n 1 >null

skrrgwasme
  • 9,358
  • 11
  • 54
  • 84
-7

I always just used;

set ERRORLEVEL=0

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

cirrus
  • 5,624
  • 8
  • 44
  • 62
  • 35
    It's easy but it´s a really bad idea, as this creates a variable named `errorlevel` which overlays the internal pseudo variable `errorlevel` – jeb Dec 04 '14 at 16:55
  • 7
    Crikey, you're right! Wow, looks like I've been dodging bullets for years :) – cirrus Dec 04 '14 at 17:11