我有一个构建后事件,该事件为ac#项目运行一些命令。最后一条命令有时会导致ERRORLEVEL值不等于零,然后构建失败。
我想附加一条命令行,以将ERRORLEVEL值始终设置为零。最方便的方法是什么?
Answers:
似乎可以解决问题:
ver > nul
并非所有方法都能正常工作,并且不清楚原因。例如,以下内容不会:
echo. > nul
cls > nul
"ver"
是一个内部命令,但是您怎么知道"help"
呢?许多中列出的命令"help"
是“外部”的命令,如:Find.exe
,Findstr.exe
,Help.exe
,Subst.exe
,Wmic.exe
,Xcopy.exe
,...
在构建前或构建后事件中,如果可执行文件的返回码大于零,并且对可执行文件的调用不是构建前或构建后事件的最后一行,则可以通过一种快速方法将其静音并避免触发检查是否为非零errorlevel
是在失败行之后跟随显式返回零的行:
cmd /c "exit /b 0"
这实质上是前面提到的解决方案的通用组合,不仅可以用于构建前或构建后事件的最后一行。
<some failing command> || cmd /c "exit /b 0"
用作一体式内胆。
cmd /c "exit /b 9009"
,但是将其设置为0似乎有点过头了。ver > nul
(内部命令)与加载另一个带有shell的命令shell副本相比,其工作开销也更少cmd /c "exit /b 0"
吗?
/b
不需要这样cmd /c “exit 0”
的作品也没关系。
如果这是“构建后事件”之类的代码段,则可以添加以下内容:
(...) || ver > nul
在最后一条命令的末尾。
或者
cmd /c "exit /b 0"
非常干净而且没有习惯-知道Windows shell的读者会知道正在发生什么以及您的意图是什么。
但是,如果您使用的是批处理脚本,则可能要使用subrotines,它与akf答案中的“子批处理脚本”轻巧等效。
有一个子程序:
:reset_error
exit /b 0
然后就
call :reset_error
无论您在何处需要它。
这是一个完整的示例:
@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
哪个输出:
After :raise_error ERRORLEVEL = 1
After :empty ERRORLEVEL = 1
After :reset_error ERRORLEVEL = 0
如您所见-仅通过goto:eof调用并返回还不够。
这是其他一些重置ErrorLevel
状态的方法,甚至在MS-DOS中也可以(至少对于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
以下方法仅在MS-DOS中起作用:
command /? > nul
fc nul nul > nul
keyb > nul
为了完整起见,这会将ErrorLevel
状态设置为1
,对Windows和MS-DOS均有效:
< nul find ""
以下功能在具有以下功能的现代Windows(基于NT)系统中起作用cmd.exe
:
rem /* This clears `ErrorLevel`; the SPACE can actually be replaced by an
rem arbitrary sequence of SPACE, TAB, `,`, `;`, `=`, NBSP, VTAB, FF: */
(call )
的SPACE(或更确切地说,一个或多个标准的令牌分离器,它们是任意的序列SPACE(码0x20
), TAB(代码0x09
), ,,
,;
,=
(NBSP代码0xFF
), VTAB(代码0x0B
)和FF(码0x0C
))是强制的; 如果您忽略它,ErrorLevel
则改为设置:
rem // This sets `ErrorLevel` to `1`:
(call)
DosTips.com上有一个不错的线程,该技术就出现了。
这是另一种方法,但是它访问文件系统,因此可能会慢一些:
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
>nul
在每个可能失败的命令之后添加-这似乎可以防止构建失败。
您仍然可以通过检查来检查命令的结果%errorlevel%
。
例如:
findstr "foo" c:\temp.txt>nul & if %errorlevel% EQU 0 (echo found it) else (echo didn't find it)
复习所有其他答案后,我决定找到哪种方法最有效地重置ERRORLEVEL。我制作了一个快速脚本,记录了执行每个脚本的时间:
"cmd /c "exit /b 0"", "cd .", "ver", "type nul", and "VERIFY"
这是输出:
cmd / v:on / c set ^“ q = ^” ^“&timeit.cmd” cmd / c ^!q ^!exit / b 0 ^!q ^!“” cd“” ver“”类型nul“ “校验”
cmd / c“退出/ b 0”采取了0:0:0.02(总计0.02s)
光盘 花费了0:0:0.00(共0.00秒)
Microsoft Windows [版本10.0.18362.836]
ver采取了0:0:0.00(共0.00s)
nul类型花费了0:0:0.00(总共0.00s)
验证已关闭。验证时间为0:0:0.00(总计0.00秒)
这花费了0:0:0.06(总共0.06s)
Measure-Command {command}
在Powershell中使用with进行审查后,我发现它只是被真正接受了cd .
,cmd /c "exit /b 0"
我做错了吗?
我建议要么cd .
还是type nul
因为无论对控制台的输出足迹,也不会在任何程度放缓。
是的,我很无聊
cmd /C exit [/B] 0
应该是自cmd.exe
打开和关闭新实例以来最慢的时间;其他都是内部命令,因此没有文件系统访问权限来查找可执行文件……