我有一个控制台应用程序。与此应用程序的交互是通过TCP / IP完成的。
我也有一个测试框架,它基本上是BATCH脚本的集合(...不是我的错)。这个测试框架对每个测试的作用基本上是这样的:
start /min "myapplication.exe"
并等待收到应用程序启动并运行的验证。我目前遇到的一个问题是,由于某些内部错误,应用程序会过早退出。我想区分失败的测试和应用程序崩溃。我对此的唯一指示是应用程序的退出代码。
所以,我尝试了以下内容:
start /min cmd /c "myapplication.exe || echo %errorLevel% > exitcode.txt"
然后在测试脚本中
if exist exitcode.txt (
set /p exitcode=<exitcode.txt
echo ERROR: myapplication.exe returned exitcode %exitcode%.
goto error
) else (
goto do_processing
)
但由于一些奇怪的原因,文本文件永远不会出现,即使我有时会得到关于应用程序崩溃的对话框,即使我强行使其失败并使用已知的非零退出代码。测试只是通过do_processing
而且(当然)导致失败。
修改 我跑的时候
start /min cmd /c "nonsense || echo %errorLevel% > test.txt"
我有时获取包含字符串9009的文本文件,但有时该文本文件包含字符串0
,或者有时1
,...那是什么。 ..?!
EDIT2 如果您输入
cmd /k "nonsense || echo %errorLevel%"
(请注意/k
选项),您会在新窗口中看到0
,但如果您输入echo %errorlevel%
,则会获得1
....
我知道批次不是很理智,但它至少应该一直疯狂 ......
关于可能会发生什么的任何想法?
答案 0 :(得分:13)
在解析语句时会发生%errorLevel%
之类的正常扩展,并且在一次传递中解析整个CMD / C命令行,因此获得的值是命令运行之前存在的值(始终为0) )。
您可以在https://stackoverflow.com/a/4095133/1012053获得更准确的解释。最初可能很难理解阶段的重要性,但值得努力。
要解决您的问题,您必须延迟变量的扩展,直到您的exe运行。
您有两种选择:
选项1)使用CALL进行延迟的扩展。
在批处理文件中,您可以将百分比加倍。但是使用CMD / C运行的命令在命令行上下文中运行,而不是在批处理下运行。将百分比加倍在命令行下不起作用。
相反,您必须将插入符号(cmd.exe转义字符)引入变量名称。第一阶段的扩展发生在处理转义之前,因此它会查找带有插入符号的名称,但找不到它。如果未找到,则命令行解析器会在找不到变量时保留原始文本。接下来处理特殊字符并消耗转义。因此,当CALL循环扩展发生时,它会看到正确的变量名称。
start /min cmd /c "myapplication.exe || call echo %^errorLevel% > exitcode.txt"
我相信您在批处理脚本中发出START命令,因此您还必须加倍百分比以防止父批处理脚本扩展ERRORLEVEL。
start /min cmd /c "myapplication.exe || call echo %%^errorLevel%% > exitcode.txt"
选项2)使用延迟展开
延迟扩展语法为!errorlevel!
而非%errorlevel%
。但在使用它之前,必须启用延迟扩展。在批处理脚本中,您将使用setlocal enableDelayedExpansion
,但这在命令行上下文中不起作用。相反,您必须使用cmd.exe /v:on
选项。
假设您的批处理脚本未启用延迟扩展,那么您只需使用以下内容:
start /min cmd /v:on /c "myapplication.exe || echo !errorLevel! > exitcode.txt"
但是,如果批处理脚本启用了延迟扩展,则必须转义!
,以便父批处理脚本不会扩展ERRORLEVEL。请注意,您仍然必须使用/v:on
,因为STARTed子流程(通常)默认为禁用延迟扩展。
start /min cmd /v:on /c "myapplication.exe || echo ^!errorLevel^! > exitcode.txt"
答案 1 :(得分:2)
正如here所述,您必须使用call
代替start
才能评估退出代码。 call
将在相同的变量环境中启动脚本,而start将在新的脚本中运行,而第一个脚本无法访问该脚本。
答案 2 :(得分:1)
另一种解决方案可能是使用&
代替||
start myapplication.exe ^& echo %errorLevel% ^> exitcode.txt
^
是一个转义字符,因此在开头内部而非外部评估here。
这对我有用。希望它可以帮到某人。