Можно предотвратить Microsoft Error Reporting для отдельного приложения?

У нас есть неуправляемое приложение C++, которое использует сторонние API для чтения файлов CAD. На определенных поврежденных файлах CAD сторонняя библиотека отказывает и снижает наш EXE с ним. Из-за этого нашего главного приложения отдельный EXE, и таким образом это не становится затронутым катастрофическим отказом. Howevever, мы заканчиваем с раздражающими диалоговыми окнами Microsoft Error Reporting.

Я не хочу отключать Microsoft Error Reporting в масштабе всей системы. Существует ли способ выключить сообщение об ошибке для отдельного приложения, так, чтобы, если это отказывает, это отказало тихо без ошибочных всплывающих диалоговых окон?

6
задан Elan 5 August 2010 в 15:37
поделиться

4 ответа

В Vista и более поздних версиях функция API WerAddExcludedApplication может использоваться для исключения указанного исполняемого файла приложения из отчетов об ошибках. Насколько мне известно, в XP и других устаревших версиях ОС подобного варианта нет.

Однако, поскольку WER срабатывает только в случае необработанных исключений приложений, вы должны иметь возможность подавить его, добавив в свой EXE-файл обработчик исключений, охватывающий все исключения. См. векторную обработку исключений для некоторых идей о том, как этого добиться.

Обратите внимание, что подавление всех необработанных исключений, как правило, является плохой идеей (и, например, приведет к тому, что ваше приложение не пройдет сертификацию Windows Logo), поэтому вам не следует использовать этот метод без разбора ...

5
ответ дан 8 December 2019 в 13:43
поделиться

Да, ты можешь кое-что сделать. Вызовите SetUnhandledExceptionFilter () в методе main (), чтобы зарегистрировать обратный вызов. Он будет вызываться, когда никто не будет добровольно обрабатывать исключение, непосредственно перед появлением диалогового окна Microsoft WER.

На самом деле выполнение чего-либо в этом обратном вызове чревато проблемами. Программа неизменно умирала с чем-то неприятным, например, с исключением AccessViolation. Что часто происходит из-за повреждения кучи. Попытка сделать что-то вроде отображения окна сообщения, чтобы сообщить пользователю, является проблематичной, когда куча является тостовой. Тупик всегда таится за углом, готовый просто заблокировать программу без какой-либо диагностики.

Единственное, что можно сделать, это иметь вспомогательный процесс, который охраняет ваш основной процесс. Разбудите его, сигнализировав именованное событие в вашем обратном вызове. Предоставьте ему необходимую информацию об исключении с помощью файла с отображением в память. Помощник может делать практически все, что захочет, когда видит, что событие сигнализируется. В том числе показ сообщения, снятие минидампа. И завершение основного процесса.

Именно так работает помощник Microsoft WerFault.

5
ответ дан 8 December 2019 в 13:43
поделиться

Ответ Ханса Пассанта о 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;
}

И где-нибудь в вашей программе (возможно, как можно раньше) установите обратный вызов:

SetUnhandledExceptionFilter(UnhandledExceptionCallback);

Это должно сделать то, что вы хотите - позволить любым сбоям этой конкретной программы молча умереть.

Однако следует отметить еще кое-что: каждый раз, когда вы добавляете сторонние компоненты (библиотеки DLL, OCX и т. Д.), Существует риск того, что один из них может также вызвать SetUnhandledExceptionFilter и, таким образом, заменить ваш обратный вызов своим собственным. Однажды я столкнулся с элементом управления ActiveX, который при создании экземпляра устанавливал собственный обратный вызов. И что еще хуже, ему не удалось восстановить исходный обратный вызов, когда он был уничтожен. Это казалось ошибкой в ​​их коде, но, несмотря на это, мне пришлось предпринять дополнительные шаги, чтобы гарантировать, что мой желаемый обратный вызов был по крайней мере восстановлен, когда это должно было произойти после того, как их управление было отключено. Поэтому, если вы обнаружите, что это иногда не работает для вас, даже если вы знаете, что правильно настроили обратный вызов, вы можете столкнуться с чем-то похожим.

5
ответ дан 8 December 2019 в 13:43
поделиться

Я не совсем уверен, но, возможно, SetErrorMode или SetThreadErrorMode подойдет вам?

0
ответ дан 8 December 2019 в 13:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: