使用"cmd"和"start"命令启动应用程序的退出代码

Rod*_*uis 7 windows batch-file command-prompt exit-code console-application

我有一个控制台应用程序.与此应用程序的交互是通过TCP/IP完成的.

我也有一个测试框架,它基本上是BATCH脚本的集合(...不是我的错).这个测试框架对每个测试的作用基本上是这样的:

  1. start /min "myapplication.exe" 并等到收到应用程序启动并运行的验证.
  2. 通过TCP/IP向此应用程序发送命令,接收其回复,并检查时间和值是否与特定测试所期望的一致.

我目前遇到的一个问题是,由于某些内部错误,应用程序会过早退出.我想区分失败的测试和应用程序崩溃.我对此的唯一指示是应用程序的退出代码.

所以,我尝试了以下内容:

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
)
Run Code Online (Sandbox Code Playgroud)

但由于一些奇怪的原因,文本文件永远不会出现,即使我有时会得到关于应用程序崩溃的对话框,即使我强行使用已知的非零退出代码使其失败.测试刚刚结束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....

我知道批次不是很理智,但至少应该一直疯狂 ......

关于可能会发生什么的任何想法?

dbe*_*ham 13

%errorLevel%解析语句时会发生正常扩展,并且在一次传递中解析整个CMD/C命令行,因此获得的值是命令运行之前存在的值(始终为0).

您可以在/sf/answers/286659341/上获得更准确的解释.一开始可能很难理解阶段的重要性,但值得努力.

要解决您的问题,您必须延迟变量的扩展,直到您的exe运行.

您有两种选择:

选项1)使用CALL进行延迟的扩展.

在批处理文件中,您可以将百分比加倍.但是使用CMD/C运行的命令在命令行上下文中运行,而不是在批处理下运行.将百分比加倍在命令行下不起作用.

相反,您必须将插入符号(cmd.exe转义字符)引入变量名称.第一阶段的扩展发生在处理转义之前,因此它会查找带有插入符号的名称,但找不到它.如果未找到,则命令行解析器会在找不到变量时保留原始文本.接下来处理特殊字符并消耗转义.因此,当CALL循环扩展发生时,它会看到正确的变量名称.

start /min cmd /c "myapplication.exe || call echo %^errorLevel% > exitcode.txt"
Run Code Online (Sandbox Code Playgroud)

我相信您在批处理脚本中发出START命令,因此您还必须加倍百分比以防止父批处理脚本扩展ERRORLEVEL.

start /min cmd /c "myapplication.exe || call echo %%^errorLevel%% > exitcode.txt"
Run Code Online (Sandbox Code Playgroud)

选项2)使用延迟扩展

延迟扩展语法!errorlevel!代替%errorlevel%.但在使用它之前,必须启用延迟扩展.在您将使用的批处理脚本中setlocal enableDelayedExpansion,但这在命令行上下文中不起作用.相反,您必须使用cmd.exe /v:on选项.

假设您的批处理脚本未启用延迟扩展,那么您只需使用以下内容:

start /min cmd /v:on /c "myapplication.exe || echo !errorLevel! > exitcode.txt"
Run Code Online (Sandbox Code Playgroud)

但是,如果批处理脚本启用了延迟扩展,则必须将其转义,!以便父批处理脚本不会扩展ERRORLEVEL.请注意,您必须仍然使用,/v:on因为STARTed子流程(通常)默认为禁用延迟扩展.

start /min cmd /v:on /c "myapplication.exe || echo ^!errorLevel^! > exitcode.txt"
Run Code Online (Sandbox Code Playgroud)