我有一个用C++编写并使用Visual Studio 2015编译的命令行应用程序。

我需要确保在自动,无人值守的功能测试期间,特别是在断言失败的情况下(从assert()转换为标准<cassert>),此应用程序不会被错误对话框阻止。

最初,我认为https://stackoverflow.com/a/6925695/393756中建议的以下调用可以完成此任务,但没有成功:

_set_error_mode(_OUT_TO_STDERR);

通过试验,我最终发现以下代码可以达到预期的效果,至少在断言对话框失败时:
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);

_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);

_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);

_CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);

问题:
  • 为什么_set_error_mode(_OUT_TO_STDERR)不够用?如果我正确理解documentation,则应该知道。
  • 为什么 _CrtSetReportMode(_CRT_ASSERT) (加上相关的_CrtSetReportFile()调用)不足以禁用对话断言?显然我还需要配置_CRT_ERROR
  • 为了确保没有打开任何对话框,我应该调用 SetErrorMode() ,如果可以,请使用什么参数?
  • 我应该选择 SetThreadErrorMode() 吗?
  • 最佳答案

    _set_error_mode配置assert_CrtSetReportMode配置 _CrtDbgReport ,它仅在CRT的调试版本中定义,并通过 _ASSERTE 等宏在内部使用。

    尽管_set_error_mode应该足以禁用assert中的消息框,但这还不够,因为assert调用了abort。在调试版本中,abort的默认行为包括_WRITE_ABORT_MSG,它报告运行时错误,该错误会调用_CrtDbgReportW来报告_CRT_ERROR。您可以通过 _CrtSetReportMode _set_abort_behavior更改中止行为,而无需使用(0, _WRITE_ABORT_MSG)来避免这种情况。但是,鉴于您的目标是禁止在调试版本中显示所有消息框,因此对于CRT内部使用_CrtSetReportMode和调用_ASSERTE的相关宏,您仍然需要_CrtDbgReport

    要配置Windows错误报告,请在进程启动时调用SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX)。如果子进程应使用默认错误模式而不是继承此模式,请在CREATE_DEFAULT_ERROR_MODE调用中使用CreateProcess创建标志。

    07-27 14:07