Batch file 编译结果/退出的批处理文件错误或cl.exe

Batch file 编译结果/退出的批处理文件错误或cl.exe,batch-file,visual-studio-2013,Batch File,Visual Studio 2013,我正在编写一个批处理文件,用于测试头策略(每个头必须包含/解析其自身的依赖项),但cl.exe似乎返回了成功,尽管它实际上失败了 无注释的脚本是: @echo off set FNAME=temp set OBJFILE=%FNAME%.obj set SRCFILE=%FNAME%.cc for /f "delims=|" %%i in ('dir /b /s ..\include\*.h') do ( ( echo #include "%%i" & echo void t

我正在编写一个批处理文件,用于测试头策略(每个头必须包含/解析其自身的依赖项),但cl.exe似乎返回了成功,尽管它实际上失败了

无注释的脚本是:

@echo off

set FNAME=temp
set OBJFILE=%FNAME%.obj
set SRCFILE=%FNAME%.cc

for /f "delims=|" %%i in ('dir /b /s ..\include\*.h') do (
    ( echo #include "%%i" & echo void test^(^){} ) > %SRCFILE%
    echo %%i
    "%VCINSTALLDIR%\bin\cl.exe" /c /W4 %SRCFILE% > NUL 2>&1

    if not ERRORLEVEL 0 goto failed
)
goto success

:failed
echo.
echo Compile failed.
goto fin

:success
echo.
echo Success.
goto fin

:fin
if exist %OBJFILE% del %OBJFILE% > NUL
if exist %SRCFILE% del %SRCFILE% > NUL
我怀疑错误在于errorlevel检测(我已经读过,以及其他关于它的警告的SO帖子),但是所有尝试的变体也以同样的方式失败,这让我思考。我可能完全错了,所以我打算和ProcMon核实一下——但遗憾的是,它现在崩溃了

只是我傻了吗

我目前正在使用
FakeType blah强制头文件失败,如果重定向到文件,cl.exe将输出该代码:

...\include\fail.h(1) : error C2146: syntax error : missing ';' before identifier 'blah'
...\include\fail.h(1) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

程序通常通过大于零的ERRORLEVEL值返回错误代码;但是,cl.exe可能会在出现错误时返回ERRORLEVEL的正值或负值,如果正常,则返回值为零。通常的形式:

if errorlevel num ...
如果errorlevel大于或等于给定的数字,则为true,因此

if not ERRORLEVEL 0 goto failed
当errorlevel小于零时,将为true。有两种方法可以测试errorlevel是否为零:

if errorlevel 0 if not errorlevel 1 goto success
也就是说,如果errorlevel大于或等于零且小于1。也许最清晰的方法是直接比较errorlevel值:

if !errorlevel! equ 0 goto success

请记住,此表单需要在开始时使用
setlocal EnableDelayedExpansion
命令。

如果需要,请尝试
if!错误等级!neq 0转到失败
,使用
设置本地启用延迟扩展
,因为
如果不是错误级别0…
表示:“如果错误级别小于0”。仔细阅读
if/?
中的描述,如果ERRORLEVEL 1 goto失败,请尝试
,因为可能没有必要。@Aacini就是这个!与
if
的细微差别。。。你能把它作为一个答案,我会接受的,谢谢。@JosefZ这似乎是可行的,尽管我不相信cl.exe永远不会返回负值(没有声明),因此我总是使用0!额外的细节值得称赞,希望将来能帮助别人。我选择后一种形式,因为它在语法上更有效;)但是
如果!错误等级!equ 0 goto success
for
循环中跳出,可能会中止。因此,您需要使用
if!错误等级!neq 0 goto失败
,或两个连续的
如果
在逻辑或意义上:
如果没有错误级别0 goto失败
和背靠背
如果错误级别1 goto失败
正确-我指的是使用与实际内容相反的方法:)