增强应用程序异常处理机制,新增未处理异常日志记录功能,确保在启动和运行期间捕获并记录异常信息。同时,重构配置文件加载逻辑,支持用户目录覆盖默认配置,优化 SQLite 数据库连接字符串处理,确保在不同环境下的兼容性和稳定性。

This commit is contained in:
geht
2026-05-15 17:30:30 +08:00
parent cea4781397
commit 1b280af9e2
23 changed files with 584 additions and 68 deletions

View File

@@ -4,7 +4,9 @@ using Mapster;
using Microsoft.Extensions.Configuration;
using NewLife;
using System.IO;
using System.Text;
using System.Windows;
using System.Windows.Threading;
using YY.Admin.Core;
using YY.Admin.EventBus;
using YY.Admin.Filter;
@@ -14,6 +16,7 @@ using YY.Admin.Services.Service.Print;
using YY.Admin.Setup;
using YY.Admin.ViewModels;
using YY.Admin.Views;
using YY.Admin.Core.Util;
namespace YY.Admin
{
/// <summary>
@@ -24,32 +27,116 @@ namespace YY.Admin
private IConfiguration? _configuration;
private ILoggerService? _logger;
private readonly SyncModule _syncModule = new();
public App()
{
DispatcherUnhandledException += OnDispatcherUnhandledException;
AppDomain.CurrentDomain.UnhandledException += OnUnhandledDomainException;
}
private static void TryWriteCrashLog(string headline, Exception ex)
{
try
{
var dir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "YY.Admin", "logs");
Directory.CreateDirectory(dir);
var file = Path.Combine(dir, $"crash-{DateTime.Now:yyyyMMdd-HHmmss}.txt");
var sb = new StringBuilder();
sb.AppendLine(headline);
sb.AppendLine(ex.ToString());
File.WriteAllText(file, sb.ToString(), Encoding.UTF8);
MessageBox.Show($"程序异常已写入日志:\n{file}\n\n{ex.Message}", "智能制造MES工控", MessageBoxButton.OK, MessageBoxImage.Error);
}
catch
{
MessageBox.Show($"{headline}\n{ex}", "智能制造MES工控", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
TryWriteCrashLog("UI 线程未处理异常", e.Exception);
e.Handled = true;
Shutdown(1);
}
private void OnUnhandledDomainException(object? sender, UnhandledExceptionEventArgs e)
{
if (e.ExceptionObject is Exception ex)
{
TryWriteCrashLog("域未处理异常", ex);
}
if (e.IsTerminating)
{
Environment.Exit(1);
}
}
protected override Window CreateShell()
{
return Container.Resolve<LoginWindow>();
}
protected override void OnStartup(StartupEventArgs e)
{
var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
// 构建配置
_configuration = new ConfigurationBuilder()
.SetBasePath(baseDirectory)
.AddJsonFile("Configuration/appsettings.json", optional: false, reloadOnChange: true)
.Build();
// 全局配置
TypeAdapterConfig.GlobalSettings.Default
.IgnoreNullValues(true)
.NameMatchingStrategy(NameMatchingStrategy.IgnoreCase);
try
{
var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
var cfgPath = Path.Combine(baseDirectory, "Configuration", "appsettings.json");
if (!File.Exists(cfgPath))
{
var msg = $"未找到配置文件(请确认与 YY.Admin.exe 同目录存在 Configuration\\appsettings.json\n{cfgPath}";
TryWriteStartupFailure(msg);
Shutdown(1);
return;
}
// FluentValidation 全局规则级别配置
ValidatorOptions.Global.DefaultRuleLevelCascadeMode = CascadeMode.Stop;
var userCfgPath = Path.Combine(
AppWritablePaths.EnsureDirectoryExists(AppWritablePaths.ConfigurationDirectory),
"appsettings.json");
// Mapster 全局配置
#if DEBUG
//TypeAdapterConfig.GlobalSettings.RequireExplicitMapping = true;
#endif
// 构建配置:安装目录默认 + 用户目录覆盖JeecgIntegration 等可由服务器设置写入)
_configuration = new ConfigurationBuilder()
.SetBasePath(baseDirectory)
.AddJsonFile(Path.Combine("Configuration", "appsettings.json"), optional: false, reloadOnChange: true)
.AddJsonFile(userCfgPath, optional: true, reloadOnChange: true)
.Build();
// 全局配置
TypeAdapterConfig.GlobalSettings.Default
.IgnoreNullValues(true)
.NameMatchingStrategy(NameMatchingStrategy.IgnoreCase);
base.OnStartup(e);
// FluentValidation 全局规则级别配置
ValidatorOptions.Global.DefaultRuleLevelCascadeMode = CascadeMode.Stop;
// Mapster 全局配置
#if DEBUG
//TypeAdapterConfig.GlobalSettings.RequireExplicitMapping = true;
#endif
base.OnStartup(e);
}
catch (Exception ex)
{
TryWriteCrashLog("启动阶段异常(配置/框架初始化失败)", ex);
Shutdown(1);
}
}
private static void TryWriteStartupFailure(string message)
{
try
{
var dir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "YY.Admin", "logs");
Directory.CreateDirectory(dir);
var file = Path.Combine(dir, $"startup-{DateTime.Now:yyyyMMdd-HHmmss}.txt");
File.WriteAllText(file, message, Encoding.UTF8);
MessageBox.Show($"{message}\n\n已记录{file}", "智能制造MES工控", MessageBoxButton.OK, MessageBoxImage.Error);
}
catch
{
MessageBox.Show(message, "智能制造MES工控", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
//注册
protected override void RegisterTypes(IContainerRegistry containerRegistry)