501 lines
22 KiB
C#
501 lines
22 KiB
C#
using AutoMapper;
|
||
using DryIoc;
|
||
using FATrace.Com;
|
||
using FATrace.WPLApp.MapperProfile;
|
||
using FATrace.WPLApp.RegionAdapter;
|
||
using FATrace.WPLApp.Services;
|
||
using FATrace.WPLApp.ViewModels;
|
||
using FATrace.WPLApp.Views;
|
||
using FreeSql;
|
||
using Prism.DryIoc;
|
||
using Prism.Ioc;
|
||
using Prism.Regions;
|
||
using Syncfusion.UI.Xaml.NavigationDrawer;
|
||
using System.Diagnostics;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using System.Windows;
|
||
using System.Windows.Threading;
|
||
|
||
namespace FATrace.WPLApp
|
||
{
|
||
/// <summary>
|
||
/// Interaction logic for App.xaml
|
||
/// </summary>
|
||
public partial class App : PrismApplication
|
||
{
|
||
private static System.Threading.Mutex mutex;
|
||
|
||
/// <summary>
|
||
/// 日志服务
|
||
/// </summary>
|
||
private ILogService LogService { get; set; }
|
||
|
||
/// <summary>
|
||
/// 构造函数
|
||
/// </summary>
|
||
public App()
|
||
{
|
||
try
|
||
{
|
||
//29.XX 12个平台都支持
|
||
|
||
Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("MzkwNTIzNEAzMjM5MmUzMDJlMzAzYjMyMzkzYkdsdE94VlZTSDh4SFJ4NUM2ekVIWU1TaGU1b1pUSzhrR0w4Y3FGU3dEclU9;MzkwNTIzNUAzMjM5MmUzMDJlMzAzYjMyMzkzYkVzekhzTm9UaDNWVWFlT0JIZW9wdmVIY1lJWVlVQjlBNUhxbHowalBGVHc9;Mgo+DSMBPh8sVXJ9S0d+X1JPd11dXmJWd1p/THNYflR1fV9DaUwxOX1dQl9mSXhSdUVmWHdbc3NVTmhXU00=;ORg4AjUWIQA/Gnt2XFhhQlJHfV5AQmBIYVp/TGpJfl96cVxMZVVBJAtUQF1hTH5Vd0ZjXH5WdXdSRGRYWkZ/;NRAiBiAaIQQuGjN/V09+XU9HdVRDX3xKf0x/TGpQb19xflBPallYVBYiSV9jS3tTcERgWXpfeHFWQWRcUU90Vg==;MzkwNTIzOUAzMjM5MmUzMDJlMzAzYjMyMzkzYmZrVWdTOUlpZkE0S1g5a3hkbzcvalZZRGpGYkxlVjdrRGNDb0F1emMyNmc9;MzkwNTI0MEAzMjM5MmUzMDJlMzAzYjMyMzkzYkdZTFROY2Y2Q09qT3NoY0Y5UlUxNzVUV2xOeWR4WE9nem94T2hkZzZ4TTQ9;Mgo+DSMBMAY9C3t2XFhhQlJHfV5AQmBIYVp/TGpJfl96cVxMZVVBJAtUQF1hTH5Vd0ZjXH5WdXddRWRfWkZ/;MzkwNTI0MkAzMjM5MmUzMDJlMzAzYjMyMzkzYkduVmtPWFh5NFFzOWVEemsyUzRVSEVaT0lTSUMzQzZXNWNPVVowMUVzVms9;MzkwNTI0M0AzMjM5MmUzMDJlMzAzYjMyMzkzYmFERlN1QnllWEhJV3dWaDhnVDVKRmxtZDl0SHRnSHRtOUU2U2ZvdU1EZWs9;MzkwNTI0NEAzMjM5MmUzMDJlMzAzYjMyMzkzYmZrVWdTOUlpZkE0S1g5a3hkbzcvalZZRGpGYkxlVjdrRGNDb0F1emMyNmc9");
|
||
|
||
//System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-CN");
|
||
|
||
// 授权 a717c797-59e3-48de-b6b4-574a4e03dc79
|
||
if (!HslCommunication.Authorization.SetAuthorizationCode("c04165f1-2578-4d86-ab08-a293b7552a5f"))
|
||
{
|
||
//active failed
|
||
MessageBox.Show("授权失败!当前程序只能使用8小时!");
|
||
//return;
|
||
|
||
}
|
||
else
|
||
{
|
||
//IsActive = true;
|
||
}
|
||
|
||
//SfSkinManager.ApplyStylesOnApplication = true;
|
||
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
MessageBox.Show(ex.Message);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 系统初始化
|
||
/// </summary>
|
||
protected override void OnInitialized()
|
||
{
|
||
// 应用主题样式
|
||
Syncfusion.SfSkinManager.SfSkinManager.ApplyStylesOnApplication = true;
|
||
|
||
// 先显示 Shell,避免耗时初始化阻塞界面呈现
|
||
base.OnInitialized();
|
||
|
||
// 轻量依赖获取与区域更新
|
||
LogService = Container.Resolve<ILogService>();
|
||
LogService.Info("OnInitialized-UI Ready");
|
||
|
||
if (Current.MainWindow is Window view)
|
||
{
|
||
var regionManager = Container.Resolve<IRegionManager>();
|
||
RegionManager.SetRegionManager(view, regionManager);
|
||
RegionManager.UpdateRegions();
|
||
|
||
if (view.DataContext is INavigationAware navigationAware)
|
||
{
|
||
navigationAware.OnNavigatedTo(null);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 回退:若 Prism 未成功设置主窗口,则手动创建并显示
|
||
LogService?.Error("Current.MainWindow 为 null,执行回退创建 MainView");
|
||
try
|
||
{
|
||
var fallback = new MainView();
|
||
Current.MainWindow = fallback;
|
||
fallback.Show();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogService?.Fatal($"回退创建 MainView 失败: {ex}");
|
||
}
|
||
}
|
||
|
||
// 后台异步预热耗时服务,避免阻塞 UI 线程
|
||
Task.Run(() =>
|
||
{
|
||
try
|
||
{
|
||
var fsql = Container.Resolve<IFreeSql>();
|
||
var sysRun = Container.Resolve<SysRunService>();
|
||
var DataServices = Container.Resolve<DataServices>();
|
||
var CsvServices = Container.Resolve<CsvServices>();
|
||
var readFileServices = Container.Resolve<ReadFileServices>();
|
||
LogService.Info("Background services initialized");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LogService.Error($"后台初始化失败: {ex.Message}");
|
||
}
|
||
});
|
||
}
|
||
|
||
/// <summary>
|
||
/// 启动时检测
|
||
/// </summary>
|
||
/// <param name="e"></param>
|
||
protected override void OnStartup(StartupEventArgs e)
|
||
{
|
||
//首先注册开始和退出事件
|
||
this.Startup += new StartupEventHandler(App_Startup);
|
||
this.Exit += new ExitEventHandler(App_Exit);
|
||
|
||
mutex = new System.Threading.Mutex(true, "OnlyRun_CRNS");
|
||
if (mutex.WaitOne(0, false))
|
||
{
|
||
base.OnStartup(e);
|
||
}
|
||
else
|
||
{
|
||
MessageBox.Show("程序已经在运行!", "提示");
|
||
this.Shutdown();
|
||
}
|
||
ShutdownMode = ShutdownMode.OnMainWindowClose;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 拓展区域适配器功能
|
||
/// </summary>
|
||
/// <param name="regionAdapterMappings"></param>
|
||
protected override void ConfigureRegionAdapterMappings(RegionAdapterMappings regionAdapterMappings)
|
||
{
|
||
|
||
base.ConfigureRegionAdapterMappings(regionAdapterMappings);
|
||
regionAdapterMappings.RegisterMapping(typeof(SfNavigationDrawer), Container.Resolve<SfNavigationDrawerRegionAdapter>());
|
||
}
|
||
|
||
protected override Window CreateShell()
|
||
{
|
||
try
|
||
{
|
||
return Container.Resolve<MainView>();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// 记录并回退到直接创建,避免因容器解析失败导致无界面
|
||
Debug.WriteLine($"CreateShell 容器解析 MainView 失败: {ex}");
|
||
try
|
||
{
|
||
return new MainView();
|
||
}
|
||
catch
|
||
{
|
||
throw; // 让全局异常处理捕获
|
||
}
|
||
}
|
||
}
|
||
|
||
protected override void RegisterTypes(IContainerRegistry containerRegistry)
|
||
{
|
||
//注册基础的服务
|
||
//containerRegistry.RegisterSingleton<IHostDialogService, DialogHostService>();
|
||
//containerRegistry.RegisterSingleton<IAppStartService, AppStartService>();
|
||
//containerRegistry.RegisterSingleton<IApplicationContext, ApplicationContext>();
|
||
|
||
// 基础服务注册
|
||
containerRegistry.RegisterSingleton<ILogService, LogService>();
|
||
containerRegistry.RegisterSingleton<IMapperProvider, MapperConfig>();
|
||
containerRegistry.Register(typeof(IMapper), GetMapper);
|
||
|
||
//containerRegistry.RegisterSingleton<AlarmService>();
|
||
containerRegistry.RegisterSingleton<SysRunService>();
|
||
//containerRegistry.RegisterSingleton<FlowMeterService>();
|
||
//containerRegistry.RegisterSingleton<BatchControlService>();
|
||
//containerRegistry.RegisterSingleton<TankService>();
|
||
//containerRegistry.RegisterSingleton<MachineRtDataService>();
|
||
|
||
containerRegistry.RegisterSingleton<DataServices>();
|
||
containerRegistry.RegisterSingleton<CsvServices>();
|
||
containerRegistry.RegisterSingleton<ReadFileServices>();
|
||
containerRegistry.RegisterSingleton<NavigationServices>();
|
||
|
||
|
||
|
||
//// 注册 Quartz 配置选项
|
||
//containerRegistry.RegisterInstance<IOptions<QuartzOptions>>(
|
||
// Options.Create(new QuartzOptions()) // 使用默认配置
|
||
//);
|
||
|
||
////在 DI 容器中注册 CustomJobFactory
|
||
//containerRegistry.RegisterSingleton<CustomJobFactory>();
|
||
//containerRegistry.RegisterSingleton<QuartzSchedulerService>();
|
||
|
||
//////注册设备服务
|
||
////containerRegistry.RegisterSingleton<MachineDataService>();
|
||
//containerRegistry.RegisterSingleton<CanDriveService>();
|
||
//containerRegistry.RegisterSingleton<LinDriveService>();
|
||
//containerRegistry.RegisterSingleton<MachineRtDataService>();
|
||
//containerRegistry.RegisterSingleton<DataRecordService>();
|
||
//containerRegistry.RegisterSingleton<HighSpeedDataService>();
|
||
////containerRegistry.RegisterSingleton<PPCService>();
|
||
//containerRegistry.RegisterSingleton<SysRunService>();
|
||
|
||
//containerRegistry.RegisterSingleton<ComActionService>();
|
||
|
||
//containerRegistry.RegisterSingleton<ProRuntimeService>();
|
||
|
||
//var LocalDbFath= @"Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=@Address@.mdf;Integrated Security=True;Connect Timeout=30;".Replace("@Address@", ConfigHelper.GetValue("LocalDBPath"));
|
||
var Constr = FATrace.Com.ConfigHelper.GetRequiredString("connecting");
|
||
|
||
//注册IFreeSql实例 单例
|
||
containerRegistry.RegisterSingleton<IFreeSql>(() =>
|
||
{
|
||
IFreeSql Fsql = new FreeSqlBuilder()
|
||
//.UseConnectionString(DataType.SqlServer, "Data Source=CT-PC;user instance=false;Initial Catalog=KylinEMS;Encrypt=True;TrustServerCertificate=True;User ID=sa;Password=12345678")
|
||
//.UseConnectionString(FreeSql.DataType.SqlServer, "Data Source=CT-PC;user instance=false;Initial Catalog=CapMachine;Encrypt=True;TrustServerCertificate=True;User ID=sa;Password=12345678")
|
||
.UseConnectionString(FreeSql.DataType.SqlServer, Constr)
|
||
//.UseConnectionString(FreeSql.DataType.SqlServer, LocalDbDir)
|
||
//.UseConnectionString(FreeSql.DataType.Sqlite, Con)
|
||
.UseAutoSyncStructure(true)
|
||
.Build();
|
||
return Fsql;
|
||
});
|
||
|
||
|
||
//containerRegistry.RegisterSingleton<INavigationMenuService, NavigationMenuService>();
|
||
containerRegistry.RegisterForNavigation<MainView, MainViewModel>();
|
||
containerRegistry.RegisterForNavigation<DashboardView, DashboardViewModel>("DashBoardView");
|
||
//containerRegistry.RegisterForNavigation<UserView, UserViewModel>();
|
||
containerRegistry.RegisterForNavigation<FootView, FootViewModel>();
|
||
containerRegistry.RegisterForNavigation<HeadView, HeadViewModel>();
|
||
//containerRegistry.RegisterForNavigation<ProFlowView, ProFlowViewModel>();
|
||
//containerRegistry.RegisterForNavigation<ReportView, ReportViewModel>();
|
||
containerRegistry.RegisterForNavigation<HelpManualView, HelpManualViewModel>();
|
||
containerRegistry.RegisterForNavigation<HistoryAlarmView, HistoryAlarmViewModel>();
|
||
// 原料使用查询页
|
||
containerRegistry.RegisterForNavigation<RawProUseView, RawProUseViewModel>();
|
||
// 原料入库查询页
|
||
containerRegistry.RegisterForNavigation<RawProInputView, RawProInputViewModel>();
|
||
|
||
// 文件导入日志查询页
|
||
containerRegistry.RegisterForNavigation<FileImportLogView, FileImportLogViewModel>();
|
||
|
||
// 用户管理
|
||
containerRegistry.RegisterForNavigation<UserManageView, UserManageViewModel>();
|
||
// 称重用户管理
|
||
containerRegistry.RegisterForNavigation<WeightUserManageView, WeightUserManageViewModel>();
|
||
|
||
// 工厂/OEM Excel 导入数据查询页
|
||
containerRegistry.RegisterForNavigation<FactoryRawInboundView, FactoryRawInboundViewModel>();
|
||
containerRegistry.RegisterForNavigation<FactoryInboundView, FactoryInboundViewModel>();
|
||
containerRegistry.RegisterForNavigation<FactoryMaterialWithdrawalView, FactoryMaterialWithdrawalViewModel>();
|
||
containerRegistry.RegisterForNavigation<FactoryInventoryTransactionView, FactoryInventoryTransactionViewModel>();
|
||
containerRegistry.RegisterForNavigation<FactoryProductionRecordView, FactoryProductionRecordViewModel>();
|
||
containerRegistry.RegisterForNavigation<FactoryOutboundView, FactoryOutboundViewModel>();
|
||
containerRegistry.RegisterForNavigation<FactoryInOutboundView, FactoryInOutboundViewModel>();
|
||
containerRegistry.RegisterForNavigation<OEMInboundView, OEMInboundViewModel>();
|
||
containerRegistry.RegisterForNavigation<OEMOutboundView, OEMOutboundViewModel>();
|
||
containerRegistry.RegisterForNavigation<OEMInventoryTransactionView, OEMInventoryTransactionViewModel>();
|
||
containerRegistry.RegisterForNavigation<OEMRawUsageInfoView, OEMRawUsageInfoViewModel>();
|
||
|
||
// 用户登录
|
||
containerRegistry.RegisterForNavigation<LoginView, LoginViewModel>("LoginView");
|
||
containerRegistry.RegisterForNavigation<HistoryAlarmView, HistoryAlarmViewModel>();
|
||
// 日志查看
|
||
containerRegistry.RegisterForNavigation<LogView, LogViewModel>("LogView");
|
||
|
||
//containerRegistry.RegisterForNavigation<RealTimeChartView, RealTimeChartViewModel>();
|
||
//containerRegistry.RegisterForNavigation<UserManageView, UserManageViewModel>();
|
||
//containerRegistry.RegisterForNavigation<ActionLogView, ActionLogViewModel>();
|
||
//containerRegistry.RegisterForNavigation<FooterView, FooterViewModel>();
|
||
//containerRegistry.RegisterForNavigation<ProStepConfigPsView, ProStepConfigPsViewModel>();
|
||
//containerRegistry.RegisterForNavigation<ProStepConfigMainView, ProStepConfigMainViewModel>();
|
||
//containerRegistry.RegisterForNavigation<QuickMeterStepView, QuickMeterStepViewModel>();
|
||
//containerRegistry.RegisterForNavigation<HistoryDataView, HistoryDataViewModel>();
|
||
//containerRegistry.RegisterForNavigation<CANConfigView, CANConfigViewModel>();
|
||
//containerRegistry.RegisterForNavigation<LINConfigView, LinConfigViewModel>();
|
||
|
||
|
||
//注册Dialog视图时绑定VM
|
||
containerRegistry.RegisterDialog<DialogUserEditView, DialogUserEditViewModel>("DialogUserEditView");
|
||
containerRegistry.RegisterDialog<DialogWeightUserEditView, DialogWeightUserEditViewModel>("DialogWeightUserEditView");
|
||
//containerRegistry.RegisterDialog<DialogCreateProView, DialogCreateProViewModel>();
|
||
//containerRegistry.RegisterDialog<DialogEditProView, DialogEditProViewModel>();
|
||
//containerRegistry.RegisterDialog<DialogChartRtConfigView, DialogChartRtConfigViewModel>();
|
||
//containerRegistry.RegisterDialog<DialogMeterCycleCountView, DialogMeterCycleCountViewModel>();
|
||
//containerRegistry.RegisterDialog<DialogChartGroupTabView, DialogChartGroupTabViewModel>();
|
||
//containerRegistry.RegisterDialog<DialogYAxisConfigView, DialogYAxisConfigViewModel>();
|
||
//containerRegistry.RegisterDialog<DialogHistoryChartRtConfigView, DialogHistoryChartRtConfigViewModel>();
|
||
//containerRegistry.RegisterDialog<DialogExpInfoView, DialogExpInfoViewModel>();
|
||
//containerRegistry.RegisterDialog<DialogUserView, DialogUserViewModel>();
|
||
//containerRegistry.RegisterDialog<DialogCanRwConfigView, DialogCanRwConfigViewModel>();
|
||
//containerRegistry.RegisterDialog<DialogCanLinConfigCreateView, DialogCanLinConfigCreateViewModel>();
|
||
//containerRegistry.RegisterDialog<DialogPIDConfigView, DialogPIDConfigViewModel>();
|
||
//containerRegistry.RegisterDialog<DialogLimitConfigView, DialogLimitConfigViewModel>();
|
||
//containerRegistry.RegisterDialog<DialogValveControlView, DialogValveControlViewModel>();
|
||
//containerRegistry.RegisterDialog<DialogLineSelectView, DialogLineSelectViewModel>();
|
||
//containerRegistry.RegisterDialog<DialogLineCtrView, DialogLineCtrViewModel>();
|
||
//containerRegistry.RegisterDialog<DialogStorageTankPumpControlView, DialogStorageTankPumpControlViewModel>();
|
||
//containerRegistry.RegisterDialog<DialogPumpControlView, DialogPumpControlViewModel>();
|
||
|
||
|
||
//containerRegistry.RegisterDialog<SplashScreenView, SplashScreenViewModel>();
|
||
|
||
// 使用 Syncfusion ChromelessWindow 统一 Prism 弹窗样式
|
||
containerRegistry.RegisterDialogWindow<ThemedDialogWindow>();
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将IAutoMapperProvider注入IOC容器,并对外提供IMapper注入类型。
|
||
/// </summary>
|
||
/// <param name="container"></param>
|
||
/// <returns></returns>
|
||
private IMapper GetMapper(IContainerProvider container)
|
||
{
|
||
var provider = container.Resolve<IMapperProvider>();
|
||
return provider.GetMapper();
|
||
}
|
||
|
||
|
||
#region 全局异常捕捉
|
||
|
||
void App_Startup(object sender, StartupEventArgs e)
|
||
{
|
||
//UI线程未捕获异常处理事件 (UI主线程)
|
||
this.DispatcherUnhandledException += new DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);
|
||
//Task线程内未捕获异常处理事件
|
||
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
|
||
//非UI线程未捕获异常处理事件 (例如自己创建的一个子线程)
|
||
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
|
||
}
|
||
|
||
|
||
void App_Exit(object sender, ExitEventArgs e)
|
||
{
|
||
//程序退出时需要处理的业务
|
||
LogService?.Info("App-程序退出");
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// UI线程未捕获异常处理事件(UI主线程)
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
|
||
{
|
||
//此时程序出现严重异常,将强制结束退出
|
||
try
|
||
{
|
||
HandleException(e.Exception);
|
||
//MessageBox.Show("UI线程异常:" + e.Exception.Message);
|
||
LogService.Error("UI线程异常:" + e.Exception.Message);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
HandleException(ex);
|
||
//MessageBox.Show("UI线程发生致命错误!");
|
||
LogService.Error("UI线程发生致命错误!");
|
||
}
|
||
finally
|
||
{
|
||
e.Handled = true;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 非UI线程未捕获异常处理事件(例如自己创建的一个子线程)
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
|
||
{
|
||
try
|
||
{
|
||
var exception = e.ExceptionObject as Exception;
|
||
if (exception != null)
|
||
{
|
||
HandleException(exception);
|
||
|
||
StringBuilder sbEx = new StringBuilder();
|
||
if (e.IsTerminating)
|
||
{
|
||
sbEx.Append("非UI线程发生致命错误");
|
||
}
|
||
sbEx.Append("非UI线程异常:");
|
||
|
||
if (e.ExceptionObject is Exception)
|
||
{
|
||
sbEx.Append(((Exception)e.ExceptionObject).Message);
|
||
}
|
||
else
|
||
{
|
||
sbEx.Append(e.ExceptionObject);
|
||
}
|
||
//MessageBox.Show(sbEx.ToString());
|
||
LogService.Error(sbEx.ToString());
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
HandleException(ex);
|
||
}
|
||
finally
|
||
{
|
||
//ignore
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Task线程内未捕获异常处理事件
|
||
/// </summary>
|
||
/// <param name="sender"></param>
|
||
/// <param name="e"></param>
|
||
void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
|
||
{
|
||
try
|
||
{
|
||
var exception = e.Exception as Exception;
|
||
if (exception != null)
|
||
{
|
||
HandleException(exception);
|
||
//task线程内未处理捕获
|
||
//MessageBox.Show("Task线程异常:" + e.Exception.Message);
|
||
LogService.Error($"Task线程异常");
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
HandleException(ex);
|
||
}
|
||
finally
|
||
{
|
||
//设置该异常已察觉(这样处理后就不会引起程序崩溃)
|
||
e.SetObserved();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 公共的日志记录方法
|
||
/// </summary>
|
||
/// <param name="ex"></param>
|
||
private void HandleException(Exception ex)
|
||
{
|
||
try
|
||
{
|
||
// 记录日志(兜底:LogService 未初始化时临时创建)
|
||
var logger = LogService ?? new Services.LogService();
|
||
logger.Error($"App捕捉HandleException-{ex}");
|
||
}
|
||
catch
|
||
{
|
||
// 忽略日志异常,避免二次异常导致崩溃
|
||
}
|
||
finally
|
||
{
|
||
try
|
||
{
|
||
// 友好提示,便于定位问题(避免阻塞可按需注释)
|
||
MessageBox.Show(ex.Message, "未处理异常", MessageBoxButton.OK, MessageBoxImage.Error);
|
||
}
|
||
catch { }
|
||
}
|
||
}
|
||
|
||
|
||
|
||
#endregion
|
||
|
||
|
||
}
|
||
|
||
}
|