Как отключить обработку исключений .NET Framework и вместо этого использовать мои собственные?

Я разработал программное обеспечение .NET 4, и я готов отправить его бета-пользователям. Если в программном обеспечении выбрано необработанное исключение, я бы хотел его поймать, зарегистрировать и отправить журналы мне. Я уже реализовал эту функциональность и, кажется, работает нормально, когда я запускаю ее в режиме отладки с помощью Visual Studio. Однако, когда я создал версию программного обеспечения и установил его, Microsoft.NET Framework начинает перехватывать исключения перед моим кодом. Я получаю всплывающее окно с сообщением об ошибке: "Необработанное исключение произошло в компоненте вашего приложения. Если вы нажмете" Продолжить ", приложение проигнорирует эту ошибку и попытается продолжить".

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

Я привязал свой собственный обработчик исключений с помощью этого кода:

AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

Есть ли способ отключить захват исключений .NET Framework или есть лучший способ привязать мой собственный обработчик исключений?

UPDATE: Я использую WPF. Я рассмотрю DispatcherUnhandledException и дам вам знать, разрешит ли он проблему.

ОБНОВЛЕНИЕ # 2: К сожалению, добавление обработчика в Application.Current.DispatcherUnhandledException не решило проблему. По-видимому, это отладочное всплывающее окно создается отладчиком JIT (Just-In-Time), который входит в состав Visual Studio. Мне нужно будет протестировать программное обеспечение с помощью "гражданских" Windows и посмотреть, есть ли там исключения.

ОБНОВЛЕНИЕ # 3: По какой-то причине выпуск, созданный с помощью Visual Studio, работает, но выпуск, созданный с использованием сценариев MSBuild и Dotfuscator, не работает.

Ответ 1

Я, наконец, решил проблему. Проблема не была вызвана прослушиванием неправильных исключений, а из-за отсутствия DLL из выпущенной версии.

После добавления прослушивателей для событий DispatchedUnhandledException и ThreadException я больше не получил странное всплывающее окно Microsoft.NET Framework, которое позволило пользователю продолжить запуск программного обеспечения после исключения. Однако моя собственная обработка исключений по-прежнему была нарушена.

Поскольку программное обеспечение уже рушилось в тот момент, когда должен был срабатывать обработчик исключений, у меня был catch (исключение) вокруг обработчика исключений. После удаления этого catch я наконец получил правильное сообщение об ошибке с версией выпуска и добавил отсутствующие DLL.

Урок, который я узнал (опять): не используйте пустой блок catch (исключение). Это зло.

Ответ 2

Вы не указали, какую структуру вы используете, но есть и другие события "необработанных исключений".

Для Windows Forms Application.ThreadException.

Для WPF/Silverlight Application.DispatcherUnhandledException.

Попробуйте один из этих первых, и сообщите нам, если у вас все еще есть проблемы.

Ответ 3

Похоже, что исключение выплескивается в ваш цикл сообщений приложения. В Windows Forms вы можете справиться с ними, настроив обработчик события Application.ThreadException. В WPF/Silverlight эквивалентное событие будет Application.DispatcherUnhandledException.

Вы также можете поместить try/catch в свой метод Main (если он у вас есть) для хорошей оценки, но пользовательский интерфейс, как вы заметили, обычно будет использовать исключения.

ИЗМЕНИТЬ

В WPF/Silverlight установите e.Handled = true, чтобы исключить продолжение продолжения стека.

Ответ 4

Уч... Dotfuscator может создать недопустимую сборку, которая не является JIT'able. Исключения JIT никогда не могут быть пойманы кодом пользователя. Это похоже на то, как вы не можете поймать StackOverflowException, потому что время выполнения не может гарантировать вам, что он может безопасно восстанавливаться из обнаруженного условия ошибки.

Тем не менее, вряд ли вы получите исключение JIT во время выполнения, поскольку между вашим IL и JITer существуют различные этапы проверки. Может быть, у вас есть InvalidProgramException или BadImageFormatException? Если JITter действительно терпит неудачу, это, скорее всего, ошибка во время выполнения и не должно происходить.

В любом случае, две вещи, которые вы можете проверить:

  • Запустите PEVerify на своей сломанной/рабочей сборке и сравните вывод.
  • Попробуйте NGEN на вашей сломанной сборке, чтобы узнать, можете ли вы спровоцировать ошибку.

Ответ 5

Вы можете посмотреть класс AppDomain и событие UnhandledException и Событие Application.ThreadException. Они поймают необработанные исключения, так как для исключений вы обрабатываете блок try-catch, вы можете написать вспомогательный класс для управления своими исключениями и делать то, что вам нужно. Вы даже можете записать третье событие в этом классе для обработанных исключений.

Ответ 6

// Add the event handler for handling UI thread exceptions to Windows Form Events.
    // Uses SystemThreading.
    // NOTE: Remember to turn Execption Handler OFF in the Debugger for testing!!  Debug -> Common Language Runtime Exceptions -> User-Unhandled -> OFF. 
    // NOTE: A separate Event Handler is Needed for other threads added to the Application.
    // NOTE: Methods can catch, inform, then throw for logging and emailing as well.
    // Add these to Program.cs.
    static void Main()
    {
            Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);

            // Set the unhandled exception mode to force all Windows Forms errors to go through the Handler.
            Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

           // ...
    }

    // Then put your handler in the method referenced in the event definition above.
    static void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
    {
         // Your Code ...
    }

  // Sorry for the ragged listing.  Still getting used to the editor here.

Ответ 7

Помогла ли < <20 > блок в Main()?

Ответ 8

Из документации события UnhandledException,

Это событие предоставляет уведомление о исключенные исключения. Это позволяет приложение для регистрации информации о исключение перед системой обработчик по умолчанию сообщает об исключении пользователю и завершает приложение.

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

Сначала я задал вопрос о необходимости вашего поиска.
Самый простой подход - просто принять командное соглашение о том, что Main и все функции Thread имеют встроенный try-catch.
Кажется, есть новые типы + события (DispatcherUnhandledException), чтобы поймать необработанные исключения, но я бы поставил под сомнение, стоит ли ему затягивать сложность. Это должна быть последняя линия защиты, а не первичная.
например если необработанное исключение возникает в другом потоке, вам понадобится больше кода (поскольку исключения не маршрутизируются по потокам, а просто завершают процесс).