Как получить полезную информацию об ошибках WPF .NET с компьютера пользователя? - PullRequest
15 голосов
/ 04 марта 2010

У меня есть приложение WPF, которое аварийно завершает работу, как только я получаю его на компьютерах, на которых не установлена ​​среда разработки - если это обман, я могу закрыть его, но мне не удается найти эквивалентный вопрос. Похоже, что я получаю исключение XamlParseException, но ничего более полезного, чем это. Мне нужно получить полезную информацию.

Просмотр журналов событий Windows 7 дает мне этот журнал ошибок:

Fault bucket , type 0
Event Name: CLR20r3
Response: Not available
Cab Id: 0

Problem signature:
P1: MyApp.exe
P2: 1.0.0.0
P3: 4b88323d
P4: PresentationFramework
P5: 3.0.0.0
P6: 4a174fbc
P7: 624f
P8: e1
P9: System.Windows.Markup.XamlParse
P10: 

Attached files:
C:\Users\Mark\AppData\Local\Temp\WER7DC.tmp.WERInternalMetadata.xml

These files may be available here:
C:\Users\Mark\AppData\Local\Microsoft\Windows\WER\ReportArchive
 \AppCrash_generatortestbed_4fa7dff09a9e893eb675f488392571ced4ac8_04ef1100

Analysis symbol: 
Rechecking for solution: 0
Report Id: cd55060c-271f-11df-b6ff-001e52eefb8e
Report Status: 1

Я проверил эти каталоги, и первый не существует, в то время как второй содержит файл wer, который просто перечисляет загруженные библиотеки.

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

РЕДАКТИРОВАТЬ: построение комментария @Alastair Pitts ниже, вот как я заполнил обработку исключений:

    private void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e) {
        Exception theException = e.Exception;
        string theErrorPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + "\\GeneratorTestbedError.txt";
        using (System.IO.TextWriter theTextWriter = new System.IO.StreamWriter(theErrorPath, true)){
            DateTime theNow = DateTime.Now;
            theTextWriter.WriteLine("The error time: " + theNow.ToShortDateString() + " " + theNow.ToShortTimeString());
            while (theException != null) {
                theTextWriter.WriteLine("Exception: " + theException.ToString());
                theException = theException.InnerException;
            }
        }
        MessageBox.Show("The program crashed.  A stack trace can be found at:\n" + theErrorPath);
        e.Handled = true;
        Application.Current.Shutdown();
    }

Надеюсь, я получу то, что мне нужно, таким образом. Спасибо за помощь!

Ответы [ 4 ]

15 голосов
/ 04 марта 2010

Я бы использовал процедуру для обработки события UnhandledException в домене приложения.

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

РЕДАКТИРОВАТЬ: XamlParseException происходит, когда ваше главное окно создается. Это означает, что конструктор этого окна вызывается. Если вы выполняете какую-либо логику в этом конструкторе, любые возникающие исключения выдают XamlParseException. Насколько я понимаю, обработчик UnhandledException все еще поймает это исключение.

Чтобы подключить событие UnhandledException в WPF, добавьте его в свое приложение. Xaml

<Application 
   x:Class="DispatcherUnhandledExceptionSample.App"
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   StartupUri="MainWindow.xaml"     
   DispatcherUnhandledException="App_DispatcherUnhandledException" />

, который затем добавляет метод в ваш app.cs

public partial class App : Application
{
    void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
    {
        // Process unhandled exception do stuff below

        // Prevent default unhandled exception processing
        e.Handled = true;
    }
}

* 1021 MSDN *

2 голосов
/ 03 ноября 2010

В дополнение к необработанному обработчику событий исключений, который регистрирует трассировку стека, также полезно взглянуть на аварийные дампы, генерируемые на машине репро.Вы упомянули, что это Windows 7, поэтому вы можете искать соответствующие аварийные дампы следующими способами:

  1. Панель управления -> Все элементы панели управления -> Центр поддержки -> «Просмотр проблем для отчета»«ссылка под разделом« Техническое обслуживание »/« Проверка решения не сообщенных проблем ».Это вызывает список приложений, которые потерпели крах, и вы можете углубиться в них, чтобы найти файлы дампа и информацию.Найдите ссылку «Просмотреть временную копию этих файлов» в левом нижнем углу технических деталей проблемы.Это извлечет файлы дампа и покажет их вам в окне проводника.

  2. cd / d% ProgramData% \ Microsoft \ Windows \ WER.

WER, похоже, хранит свои аварийные дампы под этим каталогом, так что я делаю dir / s / b для части имени приложения, которое, как я знаю, будет там.Например, я специально создал аварийное приложение, которое я назвал crashyapp.exe:

C:\ProgramData\Microsoft\Windows\WER>dir /s/b *crashy*
C:\ProgramData\Microsoft\Windows\WER\ReportQueue\AppCrash_crashyapp.exe_56f8d710d72e31d822d6b895c5c43a18d34acfa1_cab_2823e614
    
Этот каталог содержит файлы hdmp и mdmp для сбоя.Время подключить отладчик!
1 голос
/ 04 марта 2010

Регистрация исключений (как в ответе Аластера Питтса) поможет найти источник ошибки.

Наличие XamlParse в строке P9 предполагает, что может возникнуть проблема при инициализации элемента управления или окна из описания XAML. Может существовать сборка, на которую ссылается XAML, которая не найдена на целевом компьютере или не соответствует подписи в XAML.

Edit:

Синтаксический анализ XAML происходит в InitializeComponent (), который вызывается в конструкторе окна или элемента управления

0 голосов
/ 14 января 2016

В дополнение к ответу Алистер, InnerException дал мне подсказки, которые я искал:

public partial class App : Application {
    void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) {
        Exception ex = e.Exception;
        Exception ex_inner = ex.InnerException;
        string msg = ex.Message + "\n\n" + ex.StackTrace + "\n\n" +
            "Inner Exception:\n" + ex_inner.Message + "\n\n" + ex_inner.StackTrace + "\n\n" + 
            Utils.RegistryVersion();
        MessageBox.Show(msg, "Drop Print Batch Application Halted!", MessageBoxButton.OK);
        Utils.MailReport(msg);
        e.Handled = true;
        Application.Current.Shutdown();
    }
}
...