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

所以当我的批处理脚本突然出现在输出日志里时,

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

脚本停止死亡。

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

这里发生了什么?

这里的魔术是在退出代码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 

当运行时产生

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