У нас есть клиентское приложение для рабочего стола Windows WPF, в котором я написал логику для обработки глобального необработанного исключения, исключения уровня потока и всего.
Но когда я попытался с эталонным исключением Null и его корректной записью журналов на моей машине разработки с помощью Visual Studio, но когда мы выпускаем это приложение и пользователи устанавливают на свои машины из-за какого-то необработанного исключения приложение выходит из строя и не пишет в логах пользователей машины.
Чего мне не хватает здесь, я не знаю.
<Application x:Class="MyApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
ShutdownMode="OnExplicitShutdown"
Startup="Application_Startup"
DispatcherUnhandledException ="AppDispatcherUnhandledException">
<Application.Resources>
</Application.Resources>
</Application>
private void Application_Startup(object sender, StartupEventArgs e)
{
// Global exception handling
try
{
AppDomain.CurrentDomain.UnhandledException += new
UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
System.Windows.Forms.Application.ThreadException += new
ThreadExceptionEventHandler(Application_ThreadException);
Application.Current.DispatcherUnhandledException += new
DispatcherUnhandledExceptionEventHandler(AppDispatcherUnhandledException);
}
catch (Exception exc)
{
Logger.LogEntry(LogModel.Create(this).Fatal("AppStart"));
Logger.LogEntry(LogModel.Create(this).Fatal(exc.StackTrace));
}
}
void CurrentDomain_UnhandledException(object sender,
UnhandledExceptionEventArgs args)
{
try
{
Exception exception = (Exception)args.ExceptionObject;
Logger.LogEntry(LogModel.Create(this).Fatal("DomainLevel"));
Logger.LogEntry(LogModel.Create(this).Fatal(exception.Message));
Logger.LogEntry(LogModel.Create(this).Fatal(exception.StackTrace));
}
catch (Exception exc)
{
try
{
MessageBox.Show("Fatal Non-UI Error",
"Fatal Non-UI Error. Could not write the error to the
event log. Reason: "
+ exc.Message);
}
finally
{
Logger.LogEntry(LogModel.Create(this).Fatal("Domain
Finally"));
Logger.LogEntry(LogModel.Create(this).Fatal(exc.StackTrace));
}
}
}
void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
// Log the exception, display it, etc
try
{
Logger.LogEntry(LogModel.Create(this).Fatal("AppThread
Try"));
Logger.LogEntry(LogModel.Create(this).Fatal(e.Exception.Message));
Logger.LogEntry(LogModel.Create(this).Fatal(e.Exception.StackTrace));
}
catch (Exception exc)
{
Logger.LogEntry(LogModel.Create(this).Fatal("AppThread
Catch"));
Logger.LogEntry(LogModel.Create(this).Fatal(exc.Message));
MessageBox.Show("Fatal Non-UI Error",
"Fatal Non-UI Error. Could not write the error to the
event log. Reason: "
+ exc.Message);
}
}
void AppDispatcherUnhandledException(object sender,
DispatcherUnhandledExceptionEventArgs e)
{
{
// #if DEBUG // In debug mode do not custom-handle the
exception, let Visual Studio handle it
try
{
e.Handled = false;
// #else
ShowUnhandledException(e);
// #endif
}
catch (Exception exc)
{
Logger.LogEntry(LogModel.Create(this).Fatal(exc.StackTrace));
MessageBox.Show("Fatal Non-UI Error",
"Fatal Non-UI Error. Could not write the error to
the event log. Reason: "
+ exc.Message);
}
}
}
void ShowUnhandledException(DispatcherUnhandledExceptionEventArgs e)
{
try
{
Logger.LogEntry(LogModel.Create(this).Fatal("Dispatcher
try"));
Logger.LogEntry(LogModel.Create(this).Fatal(e.Exception.Message));
Logger.LogEntry(LogModel.Create(this).Fatal(e.Exception.StackTrace));
e.Handled = true;
}
catch (Exception exc)
{
Logger.LogEntry(LogModel.Create(this).Fatal("Dispatcher
Catch"));
Logger.LogEntry(LogModel.Create(this).Fatal(exc.Message));
MessageBox.Show("Fatal Non-UI Error",
"Fatal Non-UI Error. Could not write the error to the
event log. Reason: "
+ exc.Message);
}
}
public static void LogEntry(ILogEntry entry)
{
var log = LogManager.GetLogger(entry.SourceComponentName);
var message = string.Format("{0}::L{1} {2} - {3}", entry.SourceMemberName, entry.SourceLineNumber, entry.Text, entry.SourceFilePath.Split('\ \').LastOrDefault());
else if (entry.Level == LogLevelState.Error)
{
log.Error(message);
}
else if (entry.Level == LogLevelState.Fatal)
{
log.Fatal(message);
}
#if DEBUG
Console.WriteLine(message);
#endif
}
public static LogModel Create<T>(T source = default(T), [CallerMemberName] string callerMemberName = null, [CallerFilePath] string callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0)
{
return new LogModel
{
SourceComponentName = typeof(T).Name,
SourceMemberName = callerMemberName,
SourceFilePath = callerFilePath,
SourceLineNumber = callerLineNumber
};
}
public LogModel Fatal(string format, params object[] args)
{
Level = LogLevelState.Fatal;
Text = string.Format(format, args);
return this;
}
Edit:
В EventViewer
Первое событие:
Ошибка 15.05.2008 23:32:52 .NET Runtime 1026 Нет
Приложение: MyApp.exe
Версия Framework: v4.0.30319
Описание: процесс был прерван из-за необработанного исключения.
Информация об исключении: код исключения c0000008, адрес исключения 00007FFECBB12B10
Второе событие:
Ошибка 15/15/2018 11:32:54 PM Ошибка приложения 1000 События сбоя приложения
Неправильное имя приложения: MyApp.exe, версия: 2.0.0.1769, отметка времени: 0x5af68c0a.
Неисправное имя модуля: ntdll.dll, версия: 10.0.16299.15, отметка времени: 0x493793ea
Код исключения: 0xc0000008
Смещение ошибки: 0x0000000000002b10
Идентификатор ошибочного процесса: 0x15bd4
Время запуска ошибочного приложения: 0x01d3eb91be5a688c
Неверный путь к приложению: C: \ Program Files \ MyApp \ MyApp.exe
Неверный путь к модулю: C: \ WINDOWS \ SYSTEM32 \ ntdll.dll
Идентификатор отчета: 7c3cba0e-7438-491e-a9da-7871858212ef
Полное имя неисправного пакета:
Неправильный пакетный идентификатор приложения: