可以阻止单个应用程序的Microsoft错误报告吗?

Ela*_*lan 6 c++ crash unmanaged

我们有一个非托管C++应用程序,它利用第三方API来读取CAD文件.在某些损坏的CAD文件上,第三方库崩溃并使我们的EXE失效.因此,我们的主应用程序是一个单独的EXE,这样它就不会受到崩溃的影响.然而,我们最终得到了恼人的Microsoft错误报告对话框.

我不想在系统范围内禁用Microsoft错误报告.有没有一种方法来关闭错误报告单个应用程序,因此,如果它崩溃,它静静地崩溃没有错误弹出对话框?

mdb*_*mdb 5

在Vista及更高版本中,WerAddExcludedApplication API函数可用于从错误报告中排除指定的应用程序可执行文件.据我所知,在XP和其他传统操作系统版本上没有类似的选择.

但是,由于WER只会启动未处理的应用程序异常,因此您应该可以通过向EXE添加"catch-all"异常处理程序来抑制它.有关如何实现这一点的一些想法,请参阅向量异常处理.

请注意,抑制所有未处理的异常通常是一个坏主意(例如,会导致您的应用程序失败Windows徽标认证),因此您不应该不加区别地使用此技术...


Han*_*ant 5

是的,你可以做些什么.在main()方法中调用SetUnhandledExceptionFilter()来注册回调.在Microsoft WER对话框出现之前,当没有人自愿处理异常时,将调用它.

实际上在回调中做一些事情充满了麻烦.该程序已经死亡,总是像AccessViolation异常一样令人讨厌.这通常会被堆损坏绊倒.尝试执行诸如显示消息框以让用户知道的事情在堆吐司时很麻烦.死锁总是潜伏在拐角处,准备锁定程序而不需要任何诊断.

唯一安全的做法是有一个帮助程序来保护你的主要进程.通过在回调中发出命名事件来唤醒它.使用内存映射文件为其提供所需的异常信息.当看到事件发出信号时,助手可以做任何想做的事情.包括显示消息,采取minidump.并终止主要流程.

这正是Microsoft WerFault帮助程序的工作原理.


The*_*ish 5

Hans Passant关于SetUnhandledExceptionFilter的回答是正确的.他还提出了一些关于在回调中无法做太多的好点,因为过程的各个部分可能处于不稳定状态.

但是,从描述问题的方式来看,除了告诉系统不要提出正常的崩溃对话框之外,听起来并不想做任何事情.在这种情况下,它很容易并且应该是安全的,无论崩溃可能影响到哪个过程部分.

创建一个像这样的函数:

LONG WINAPI UnhandledExceptionCallback(PEXCEPTION_POINTERS pExceptPtrs)
{
    if (IsDebuggerPresent())
        // Allow normal crash handling, which means the debugger will take over.
        return EXCEPTION_CONTINUE_SEARCH;
    else
        // Say we've handled it, so that the standard crash dialog is inhibited.
        return EXCEPTION_EXECUTE_HANDLER;
}
Run Code Online (Sandbox Code Playgroud)

在你的程序中的某个地方(可能尽可能早)设置回调:

SetUnhandledExceptionFilter(UnhandledExceptionCallback);
Run Code Online (Sandbox Code Playgroud)

这应该做你想要的 - 允许任何特定程序的崩溃无声地死亡.

但是,还有一些需要注意的事项:每当你引入第三方组件(DLL,OCX等)时,其中一个组件也可能会调用SetUnhandledExceptionFilter,从而用自己的回调替换你的回调.我曾经遇到过一个ActiveX控件,它会在实例化时设置自己的回调.更糟糕的是,它在销毁时无法恢复原始回调.这似乎是他们的代码中的一个错误,但无论我是否必须采取额外的步骤,以确保我的所需回调至少在他们的控制被关闭后应该恢复.因此,如果您发现这似乎不适合您,即使您知道您已正确设置回调,那么您可能会遇到类似的事情.


Jer*_*fin 0

我一点也不确定,但也许SetErrorModeSetThreadErrorMode将会为你工作?