81

我有一个为 ac# 项目运行一些命令的构建后事件。最后一个命令有时会导致 ERRORLEVEL 值不等于 0,然后构建失败。

我想附加一行额外的命令以始终将 ERRORLEVEL 值设置为零。最方便的方法是什么?

4

13 回答 13

73

如果您使用,您可以从子批处理脚本exit /b 0中返回一个,而无需退出父批处理脚本。errorlevel 0

于 2009-07-11T13:45:08.600 回答
57

似乎可以解决问题:

ver > nul

并非一切都有效,目前尚不清楚原因。例如,以下内容不会:

echo. > nul
cls > nul
于 2009-07-11T13:36:50.437 回答
32

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.

于 2010-01-09T23:21:36.753 回答
18

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

于 2017-07-22T13:28:46.463 回答
17

我发现“exit 0”看起来是处理这个问题的好方法。

使用示例:

NET STOP UnderDevService /Y

出口 0

如果 UnderDevService 服务没有启动。

于 2009-07-11T13:40:36.170 回答
9

I use VERIFY or VERIFY > nul

于 2012-05-02T01:37:57.380 回答
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.

于 2016-10-11T21:54:40.657 回答
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
于 2020-10-21T18:55:00.687 回答
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 ""
于 2019-02-19T19:14:38.223 回答
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

于 2020-05-15T09:02:31.857 回答
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)
于 2010-04-15T00:11:38.537 回答
-2

I'm using this:

ping localhost -n 1 >null

于 2015-02-16T09:59:21.920 回答
-5

I always just used;

set ERRORLEVEL=0

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

于 2014-12-04T16:08:08.243 回答