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

时间:2015-02-04 10:09:49

标签: windows batch-file console-application command-prompt exit-code

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

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

  1. start /min "myapplication.exe"并等待收到应用程序启动并运行的验证。
  2. 通过TCP / IP向此应用程序发送命令,接收其回复,并检查时间和值是否与特定测试所期望的一致。
  3. 我目前遇到的一个问题是,由于某些内部错误,应用程序会过早退出。我想区分失败的测试和应用程序崩溃。我对此的唯一指示是应用程序的退出代码。

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

    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 ....

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

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

3 个答案:

答案 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

这对我有用。希望它可以帮到某人。