简体   繁体   English

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

[英]Getting the exit code of an application started with the “cmd” and “start” commands

I have a console application. 我有一个控制台应用程序。 Interaction with this application is done via TCP/IP. 与此应用程序的交互是通过TCP / IP完成的。

I also have a test framework for it, which is basically a collection of BATCH scripts (...not my fault). 我也有一个测试框架,它基本上是BATCH脚本的集合(...不是我的错)。 What this test framework does for each test is basically this: 这个测试框架对每个测试的作用基本上是这样的:

  1. start /min "myapplication.exe" and wait until verification is received that the application is up and running. start /min "myapplication.exe"并等待直到收到应用程序启动并运行的验证。
  2. send commands via TCP/IP to this application, receive its replies, and check if the timings and values agree with whatever is expected by the specific test. 通过TCP / IP向此应用程序发送命令,接收其回复,并检查时间和值是否与特定测试所期望的一致。

One problem that I'm currently encountering is that the application exits prematurely due to some internal error. 我目前遇到的一个问题是,由于某些内部错误,应用程序会过早退出。 I would like to distinguish between failed tests, and the application crashing. 我想区分失败的测试和应用程序崩溃。 The one and only indication I have for this, is the application's exit code. 我对此的唯一指示是应用程序的退出代码。

So, I tried the following: 所以,我尝试了以下内容:

start /min cmd /c "myapplication.exe || echo %errorLevel% > exitcode.txt"

and then later on in the test scripts, 然后在测试脚本中,

if exist exitcode.txt (
    set /p exitcode=<exitcode.txt
    echo ERROR: myapplication.exe returned exitcode %exitcode%.
    goto error
) else (
    goto do_processing
)

but for some strange reason, the text file never appears, even though I sometimes get a dialog about the application crashing, and even though I forcibly make it fail with a known non-zero exit code. 但由于一些奇怪的原因,文本文件永远不会出现,即使我有时会得到关于应用程序崩溃的对话框,即使我强行使用已知的非零退出代码使其失败。 The test just goes through do_processing and (of course) results in failure. 测试只是通过do_processing而且(当然)会导致失败。

EDIT When I run 编辑当我跑

start /min cmd /c "nonsense || echo %errorLevel% > test.txt"

I sometimes get a text file containing the string 9009, but other times that text file contains the string 0 , or sometimes 1 , ...What the...?! 有时得到一个包含字符串9009的文本文件,但有时候该文本文件包含字符串0 ,或者有时1 ,... ...什么...?!

EDIT2 If you type EDIT2如果输入

cmd /k "nonsense || echo %errorLevel%"

(note the /k option), you see 0 being printed in the new window, but if you then type echo %errorlevel% , you get 1 .... (注意/k选项),你看到在新窗口中打印0 ,但如果你输入echo %errorlevel% ,你得到1 ....

I knew batch was not very sane, but it should at least be consistently insane ... 我知道批次不是很理智,但至少应该一直疯狂 ......

Any ideas on what could be going on here? 关于可能会发生什么的任何想法?

Normal expansion like %errorLevel% occurs when the statement is parsed, and the entire CMD /C command line is parsed in one pass, so the value you get is the value that existed before the commands were run (always 0). 解析语句时会发生%errorLevel%等正常扩展,并且在一次传递中解析整个CMD / C命令行,因此获得的值是命令运行之前存在的值(始终为0)。

You can get a more precise explanation at https://stackoverflow.com/a/4095133/1012053 . 您可以在https://stackoverflow.com/a/4095133/1012053上获得更准确的解释。 It can be difficult to follow and understand the significance of the phases at first, but it is worth the effort. 一开始可能很难理解阶段的重要性,但值得努力。

To solve your problem you must delay expansion of the variable until after your exe has run. 要解决您的问题,您必须延迟变量的扩展,直到您的exe运行。

You have two options: 您有两种选择:

Option 1) Use CALL to get a delayed round of expansion. 选项1)使用CALL进行延迟的扩展。

In a batch file you would double the percents. 在批处理文件中,您可以将百分比加倍。 But the commands run using CMD /C are run under a command line context, not batch. 但是使用CMD / C运行的命令在命令行上下文中运行,而不是在批处理下运行。 Doubling the percents does not work under the command line. 将百分比加倍在命令行下不起作用。

Instead, you must introduce a caret (cmd.exe escape character) into the variable name. 相反,您必须将插入符号(cmd.exe转义字符)引入变量名称。 The first phase of expansion occurs before escapes are processed, so it looks for a name with the caret, and doesn't find it. 第一阶段的扩展发生在处理转义之前,因此它会查找带有插入符号的名称,但找不到它。 When not found, the command line parser preserves the original text when the variable is not found. 如果未找到,则命令行解析器会在找不到变量时保留原始文本。 Next the special characters are handled and the escape is consumed. 接下来处理特殊字符并消耗转义。 So when the CALL round of expansion occurs, it sees the correct variable name. 因此,当CALL循环扩展发生时,它会看到正确的变量名称。

start /min cmd /c "myapplication.exe || call echo %^errorLevel% > exitcode.txt"

I believe you are issuing the START command within a batch script, so you must also double the percents to prevent the parent batch script from expanding ERRORLEVEL. 我相信您在批处理脚本中发出START命令,因此您还必须加倍百分比以防止父批处理脚本扩展ERRORLEVEL。

start /min cmd /c "myapplication.exe || call echo %%^errorLevel%% > exitcode.txt"

Option 2) Use delayed expansion 选项2)使用延迟扩展

Delayed expansion syntax is !errorlevel! 延迟扩展语法是!errorlevel! instead of %errorlevel% . 而不是%errorlevel% But before you can use it, delayed expansion must be enabled. 但在使用它之前,必须启用延迟扩展。 In a batch script you would use setlocal enableDelayedExpansion , but that doesn't work in a command line context. 在批处理脚本中,您将使用setlocal enableDelayedExpansion ,但这在命令行上下文中不起作用。 Instead, you must use the cmd.exe /v:on option. 相反,您必须使用cmd.exe /v:on选项。

Assuming your batch script has not enabled delayed expansion, then you would simply use the following: 假设您的批处理脚本未启用延迟扩展,那么您只需使用以下内容:

start /min cmd /v:on /c "myapplication.exe || echo !errorLevel! > exitcode.txt"

But if your batch script has enabled delayed expansion, then you must escape the ! 但是如果您的批处理脚本启用了延迟扩展,那么您必须逃避! so that the parent batch script does not expand ERRORLEVEL. 这样父父批处理脚本不会扩展ERRORLEVEL。 Note that you must still use /v:on because the STARTed sub-process (normally) defaults to disabled delayed expansion. 请注意,您仍必须使用/v:on因为STARTed子进程(通常)默认为禁用延迟扩展。

start /min cmd /v:on /c "myapplication.exe || echo ^!errorLevel^! > exitcode.txt"

As explained here you have to use call instead of start to be able to evaluate the exit codes. 如此处所述您必须使用call而不是start来评估退出代码。 call will launch the script in the same variable environment whereas start will run it in a new one which is not accessable from the first script. call将在相同的变量环境中启动脚本,而start将在新的脚本中运行它,该脚本不能从第一个脚本访问。

Another solution may be to use & instead of || 另一种解决方案可能是使用&而不是||

start myapplication.exe ^& echo %errorLevel% ^> exitcode.txt

The ^ is an escape char, so that this is evaluated inside the start and not outside as explained here . ^是一个转义字符,所以这是启动内部评估,并没有如外界解释这里

This worked for me. 这对我有用。 Hope it helps someone. 希望它可以帮助某人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM