为什么非交互式批处理脚本认为我已按下control-C?

Har*_*ton 9 windows batch-file

因此,当输出日志中出现突然显示时,我的批处理脚本正在顺利进行:

21:27:13.99 c:\apps\w7lab-scripting>some-command
Error 3221225786
^CTerminate batch job (Y/N)? 
Run Code Online (Sandbox Code Playgroud)

并且脚本停止了.

批处理脚本在会话0中运行,所以我知道它没有收到真正的control-C,也没有我的代码调用GenerateConsoleCtrlEvent所以不能这样.唯一的线索是当时some-command正在与交互式应用程序通信,并且应用程序的控制台收到了一个控件-C.预期的行为是some-command显示其他应用程序的退出代码,然后使用相同的代码退出.批处理脚本会适当地处理错误,如果它没有停止死亡.

这里发生了什么?

Har*_*ton 14

这里的神奇之处在于退出代码3221225786,即0xC000013A或STATUS_CONTROL_C_EXIT.

交互式应用程序收到一个控件-C,但没有捕获它,因此如预期的那样,它被STATUS_CONTROL_C_EXIT中止.该some-command应用程序正确地报告这是远程应用程序的退出代码,并通过回批处理脚本.

我没有意识到的是cmd.exe,通过检查子进程是否返回STATUS_CONTROL_C_EXIT,以这种方式检测批处理脚本中的control-C.因此,通过返回此错误代码,我无意中停止了批处理脚本.

这可以通过一个简单的批处理脚本来演示:

cmd /c exit 3221225786
echo hello
Run Code Online (Sandbox Code Playgroud)

在运行时产生

C:\working\test>cmd /c exit 3221225786
^CTerminate batch job (Y/N)?
Run Code Online (Sandbox Code Playgroud)

  • 我发现这个功能很有用.它可用于从CALLed例程中干净地退出批处理.请参见http://stackoverflow.com/a/25474648/1012053 (2认同)