解决因Pull Request Merge Conflict Extension插件导致的中文乱码问题。

This commit is contained in:
QI Mingxuan
2026-05-20 15:00:21 +08:00
parent e3cfac5f09
commit 375fb832f0
+87 -91
View File
@@ -32,7 +32,6 @@ using XP.Common.Logging.Interfaces;
using XP.Common.Module;
using XP.Hardware.Detector.Module;
using XP.Hardware.Detector.Services;
using XP.Hardware.Detector.Services;
using XP.Hardware.MotionControl.Module;
using XP.Hardware.Plc.Abstractions;
using XP.Hardware.PLC;
@@ -69,7 +68,7 @@ namespace XplorePlane
{
protected override void OnStartup(StartupEventArgs e)
{
// 设置 Telerik Windows11 主题,缩 Ribbon 整体尺寸
// 设置 Telerik Windows11 主题,缩 Ribbon 整体尺寸
StyleManager.ApplicationTheme = new Windows11Theme();
// 强制使用中文 UI,确保 ImageProcessing 库显示中文
@@ -79,10 +78,10 @@ namespace XplorePlane
CultureInfo.DefaultThreadCurrentCulture = zhCN;
CultureInfo.DefaultThreadCurrentUICulture = zhCN;
// 置 Serilog 日志系统
// 置 Serilog 日志系统
ConfigureLogging();
// 获未处的异常
// 获未处的异常
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
DispatcherUnhandledException += OnDispatcherUnhandledException;
@@ -118,24 +117,24 @@ namespace XplorePlane
private void ConfigureLogging()
{
// 加载 Serilog 置 | Load Serilog configuration
// 加载 Serilog 置 | Load Serilog configuration
SerilogConfig serilogConfig = LoggingConfigLoader.LoadSerilogConfig();
// 初始化 Serilog(全局唯一)| Initialize Serilog (global singleton)
SerilogInitializer.Initialize(serilogConfig);
// 记录应用动日志 | Log application startup
// 记录应用动日志 | Log application startup
Log.Information("========================================");
Log.Information("XplorePlane 应用程庝坯动");
Log.Information("XplorePlane 应用程序启动");
Log.Information("========================================");
}
protected override void OnExit(ExitEventArgs e)
{
Log.Information("========================================");
Log.Information("XplorePlane 应用程退出");
Log.Information("XplorePlane 应用程退出");
Log.Information("========================================");
// 释放全局状思朝务资
// 释放全局状态服务资
try
{
var bootstrapper = AppBootstrapper.Instance;
@@ -143,15 +142,15 @@ namespace XplorePlane
{
var appStateService = bootstrapper.Container.Resolve<IAppStateService>();
appStateService?.Dispose();
Log.Information("全局状思朝务资已释放");
Log.Information("全局状态服务资已释放");
}
}
catch (Exception ex)
{
Log.Error(ex, "全局状思朝务资释放失败");
Log.Error(ex, "全局状态服务资释放失败");
}
// 释放射线溝资溝
// 释放射线源资源
try
{
var bootstrapper = AppBootstrapper.Instance;
@@ -159,15 +158,15 @@ namespace XplorePlane
{
var raySourceService = bootstrapper.Container.Resolve<IRaySourceService>();
raySourceService?.Dispose();
Log.Information("射线溝资溝已释放");
Log.Information("射线源资源已释放");
}
}
catch (Exception ex)
{
Log.Error(ex, "射线溝资溝释放失败");
Log.Error(ex, "射线源资源释放失败");
}
// 先止导航相机实时采集,释放资溝,靿兝回调死
// 先止导航相机实时采集,释放资源,避免回调死
try
{
var bootstrapper = AppBootstrapper.Instance;
@@ -183,7 +182,7 @@ namespace XplorePlane
Log.Error(ex, "导航相机 ViewModel 释放失败");
}
// 释放导航相机务资
// 释放导航相机务资
try
{
var bootstrapper = AppBootstrapper.Instance;
@@ -191,15 +190,15 @@ namespace XplorePlane
{
var cameraService = bootstrapper.Container.Resolve<ICameraService>();
cameraService?.Dispose();
Log.Information("导航相机务资已释放");
Log.Information("导航相机务资已释放");
}
}
catch (Exception ex)
{
Log.Error(ex, "导航相机务资释放失败");
Log.Error(ex, "导航相机务资释放失败");
}
// 释放主界面探测器帧水线资
// 释放主界面探测器帧水线资
try
{
var bootstrapper = AppBootstrapper.Instance;
@@ -207,31 +206,31 @@ namespace XplorePlane
{
var detectorFramePipelineService = bootstrapper.Container.Resolve<IDetectorFramePipelineService>();
detectorFramePipelineService?.Dispose();
Log.Information("主界面探测器帧水线资已释放");
Log.Information("主界面探测器帧水线资已释放");
}
}
catch (Exception ex)
{
Log.Error(ex, "主界面探测器帧水线资释放失败");
Log.Error(ex, "主界面探测器帧水线资释放失败");
}
// 释放SQLite数库资 | Release SQLite database resources
// 释放SQLite数库资 | Release SQLite database resources
try
{
var bootstrapper = AppBootstrapper.Instance;
if (bootstrapper != null)
{
var dbContext = bootstrapper.Container.Resolve<IDbContext>(); // 从 Prism 容器获 IDbContext 实例(例)| Get IDbContext instance from Prism container (singleton)
var dbContext = bootstrapper.Container.Resolve<IDbContext>(); // 从 Prism 容器获 IDbContext 实例(例)| Get IDbContext instance from Prism container (singleton)
dbContext?.Dispose();
Log.Information("数库资溝已戝功释放 | Database resources released successfully");
Log.Information("数库资源已成功释放 | Database resources released successfully");
}
}
catch (Exception ex)
{
Log.Error(ex, "数库资释放失败,忽略该错误继续退出 | Database resource release failed, ignoring error and continuing exit");
Log.Error(ex, "数库资释放失败,忽略该错误继续退出 | Database resource release failed, ignoring error and continuing exit");
}
// 释放 PLC 资
// 释放 PLC 资
try
{
var bootstrapper = AppBootstrapper.Instance;
@@ -239,15 +238,15 @@ namespace XplorePlane
{
var plcService = bootstrapper.Container.Resolve<IPlcService>();
plcService?.Dispose();
Log.Information("PLC 资已释放");
Log.Information("PLC 资已释放");
}
}
catch (Exception ex)
{
Log.Error(ex, "PLC 资释放失败");
Log.Error(ex, "PLC 资释放失败");
}
// 释放探测器资
// 释放探测器资
try
{
var bootstrapper = AppBootstrapper.Instance;
@@ -255,15 +254,15 @@ namespace XplorePlane
{
var detectorService = bootstrapper.Container.Resolve<IDetectorService>();
detectorService?.Dispose();
Log.Information("探测器资已释放");
Log.Information("探测器资已释放");
}
}
catch (Exception ex)
{
Log.Error(ex, "探测器资释放失败");
Log.Error(ex, "探测器资释放失败");
}
// 释放录制务资
// 释放录制务资
try
{
var bootstrapper = AppBootstrapper.Instance;
@@ -271,24 +270,24 @@ namespace XplorePlane
{
var recordingService = bootstrapper.Container.Resolve<IViewportRecordingService>();
recordingService?.Dispose();
Log.Information("录制务资已释放");
Log.Information("录制务资已释放");
}
}
catch (Exception ex)
{
Log.Error(ex, "录制务资释放失败");
Log.Error(ex, "录制务资释放失败");
}
Log.CloseAndFlush();
base.OnExit(e);
}
/// <summary>
/// 处睆未杕获的异常
/// 处理未捕获的异常
/// </summary>
private void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var exception = e.ExceptionObject as Exception;
Log.Fatal(exception, "应用程庝坑生未处的异常");
Log.Fatal(exception, "应用程序发生未处的异常");
MessageBox.Show(
$"A fatal error has occurred:\n\n{exception?.Message}\n\nPlease check the log file for details.",
@@ -298,11 +297,11 @@ namespace XplorePlane
}
/// <summary>
/// 处 UI 线程未获的异常
/// 处 UI 线程未获的异常
/// </summary>
private void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
Log.Error(e.Exception, "UI 线程生未处的异常");
Log.Error(e.Exception, "UI 线程生未处的异常");
MessageBox.Show(
$"An error has occurred:\n\n{e.Exception.Message}\n\nPlease check the log file for details.",
@@ -310,7 +309,7 @@ namespace XplorePlane
MessageBoxButton.OK,
MessageBoxImage.Error);
// 标记为已处,防止应用程崩溃
// 标记为已处,防止应用程崩溃
e.Handled = true;
}
}
@@ -332,7 +331,7 @@ namespace XplorePlane
protected override Window CreateShell()
{
// 杝剝初始化模块,确保硬件务在 MainWindow XAML 解枝剝已注册
// 提前初始化模块,确保硬件务在 MainWindow XAML 解析前已注册
if (!_modulesInitialized)
{
base.InitializeModules();
@@ -348,26 +347,26 @@ namespace XplorePlane
var shell = Container.Resolve<MainWindow>();
// 主窗加载完戝坎冝连接相机,确保所有模块和原生 DLL 已完初始化
// 主窗加载完成后再连接相机,确保所有模块和原生 DLL 已完初始化
shell.Loaded += async (s, e) =>
{
// [DEV] 导航相机连接已蔽,开阶段跳过以加快动速度
// [DEV] 导航相机连接已蔽,开阶段跳过以加快动速度
// TryConnectCamera();
// 初始化主界面探测器帧水线,开始接收探测器图事件
// 初始化主界面探测器帧水线,开始接收探测器图事件
try
{
_ = Container.Resolve<IDetectorFramePipelineService>();
}
catch (Exception ex)
{
Log.Error(ex, "初始化主界面探测器帧水线失败");
Log.Error(ex, "初始化主界面探测器帧水线失败");
}
// 若置为模拟探测器,自动初始化并动采集(无需用户手动作)
// 若置为模拟探测器,自动初始化并动采集(无需用户手动作)
await TryAutoStartSimulatedDetectorAsync();
// [DEV] 相机状通知已
// [DEV] 相机状通知已
// try
// {
// var cameraVm = Container.Resolve<NavigationPropertyPanelViewModel>();
@@ -388,9 +387,8 @@ namespace XplorePlane
}
/// <summary>
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<AUTO GENERATED BY CONFLICT EXTENSION<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Develop/XP
/// 若 App.config 中 Detector:Type = Simulated,自动初始化并坯动连续采集
/// 真实硬件类型丝块影哝。
/// 若 App.config 中 Detector:Type = Simulated,自动初始化并启动连续采集。
/// 真实硬件类型不会影响
/// </summary>
private async System.Threading.Tasks.Task TryAutoStartSimulatedDetectorAsync()
{
@@ -410,27 +408,26 @@ namespace XplorePlane
Log.Error("SimulatedDetector 自动初始化失败:{Msg}", initResult.ErrorMessage);
return;
}
Log.Information("[SimulatedDetector] 初始化功,动连续采集...");
Log.Information("[SimulatedDetector] 初始化功,动连续采集...");
var startResult = await detectorService.StartAcquisitionAsync();
if (!startResult.IsSuccess)
{
Log.Error("SimulatedDetector 动采集失败:{Msg}", startResult.ErrorMessage);
Log.Error("SimulatedDetector 动采集失败:{Msg}", startResult.ErrorMessage);
return;
}
Log.Information("[SimulatedDetector] 连续采集已动,帧将以 5 fps 挝续坑布");
Log.Information("[SimulatedDetector] 连续采集已动,帧将以 5 fps 持续发布");
}
catch (Exception ex)
{
Log.Error(ex, "SimulatedDetector 自动动异常");
Log.Error(ex, "SimulatedDetector 自动动异常");
}
}
/// <summary>
====================================AUTO GENERATED BY CONFLICT EXTENSION====================================
/// 执行授权检查,授权失败时显示错误消杯 | Perform license check, show error message on failure
/// 执行授权检查,授权失败时显示错误消息 | Perform license check, show error message on failure
/// </summary>
/// <returns>授权是坦戝功 | Whether authorization succeeded</returns>
/// <returns>授权是否成功 | Whether authorization succeeded</returns>
private bool PerformLicenseCheck()
{
try
@@ -449,7 +446,7 @@ namespace XplorePlane
return false;
}
// 临时测试模专属:订阅倒计时事件并示 | Temporary test mode only: subscribe countdown events and notify
// 临时测试模专属:订阅倒计时事件并示 | Temporary test mode only: subscribe countdown events and notify
if (licenseService.LicenseMode == XP.Common.License.Enums.LicenseMode.TemporaryTest)
{
licenseService.TestModeWarning5Min += OnTestModeWarning5Min;
@@ -457,8 +454,8 @@ namespace XplorePlane
licenseService.TestModeTimeout += OnTestModeTimeout;
MessageBox.Show(
"当为临时测试模,软件将在15分钟自动关闭。\nCurrently in temporary test mode, the software will automatically shut down after 15 minutes.",
"临时测试模 | Temporary Test Mode",
"当为临时测试模,软件将在15分钟自动关闭。\nCurrently in temporary test mode, the software will automatically shut down after 15 minutes.",
"临时测试模 | Temporary Test Mode",
MessageBoxButton.OK,
MessageBoxImage.Information);
}
@@ -468,7 +465,7 @@ namespace XplorePlane
}
catch (Exception ex)
{
Log.Error(ex, "授权检查过程中生异常 | Exception during authorization check");
Log.Error(ex, "授权检查过程中生异常 | Exception during authorization check");
MessageBox.Show(
$"授权检查异常 | Authorization check exception: {ex.Message}",
"授权失败 | Authorization Failed",
@@ -479,54 +476,53 @@ namespace XplorePlane
}
/// <summary>
/// 处临时测试模剩余5分钟警告 | Handle temporary test mode 5-minute warning
/// 处临时测试模剩余5分钟警告 | Handle temporary test mode 5-minute warning
/// </summary>
private void OnTestModeWarning5Min(object? sender, EventArgs e)
{
Application.Current.Dispatcher.Invoke(() =>
{
Log.Warning("临时测试模剩余5分钟 | Temporary test mode: 5 minutes remaining");
Log.Warning("临时测试模剩余5分钟 | Temporary test mode: 5 minutes remaining");
MessageBox.Show(
"临时测试模将在5分钟到期,请尽快保存您的工作。\nTemporary test mode will expire in 5 minutes, please save your work.",
"测试模弝杝醒 | Test Mode Reminder",
"临时测试模将在5分钟到期,请尽快保存您的工作。\nTemporary test mode will expire in 5 minutes, please save your work.",
"测试模式提醒 | Test Mode Reminder",
MessageBoxButton.OK,
MessageBoxImage.Information);
});
}
/// <summary>
/// 处临时测试模剩余1分钟警告 | Handle temporary test mode 1-minute warning
/// 处临时测试模剩余1分钟警告 | Handle temporary test mode 1-minute warning
/// </summary>
private void OnTestModeWarning1Min(object? sender, EventArgs e)
{
Application.Current.Dispatcher.Invoke(() =>
{
Log.Warning("临时测试模剩余1分钟 | Temporary test mode: 1 minute remaining");
Log.Warning("临时测试模剩余1分钟 | Temporary test mode: 1 minute remaining");
MessageBox.Show(
"临时测试模将在1分钟到期,软件将关闭,请立保存您的工作。\nTemporary test mode will expire in 1 minute, the software will shut down soon. Please save your work immediately.",
"测试模弝坳将到期 | Test Mode Expiring",
"临时测试模将在1分钟到期,软件将关闭,请立保存您的工作。\nTemporary test mode will expire in 1 minute, the software will shut down soon. Please save your work immediately.",
"测试模式即将到期 | Test Mode Expiring",
MessageBoxButton.OK,
MessageBoxImage.Warning);
});
}
/// <summary>
/// 处临时测试模超时事件(执行正常关闭程)| Handle temporary test mode timeout event (perform graceful shutdown)
/// 处临时测试模超时事件(执行正常关闭程)| Handle temporary test mode timeout event (perform graceful shutdown)
/// </summary>
private void OnTestModeTimeout(object? sender, EventArgs e)
{
Application.Current.Dispatcher.Invoke(() =>
{
Log.Warning("临时测试模已超时,执行正常关闭程 | Temporary test mode timed out, performing graceful shutdown");
// 使用正常关闭程,确保资正确释放 | Use graceful shutdown to ensure proper resource release
Log.Warning("临时测试模已超时,执行正常关闭程 | Temporary test mode timed out, performing graceful shutdown");
// 使用正常关闭程,确保资正确释放 | Use graceful shutdown to ensure proper resource release
Application.Current.MainWindow?.Close();
});
}
/// <summary>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>AUTO GENERATED BY CONFLICT EXTENSION>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Feature/TURBO-621-License
/// 在主线程上检索并连接导航相机。
/// pylon SDK 求在主线程(STA)上作,能放到坎坰线程。
/// pylon SDK 求在主线程(STA)上作,能放到后台线程。
/// </summary>
private void TryConnectCamera()
{
@@ -540,7 +536,7 @@ namespace XplorePlane
catch (DeviceNotFoundException)
{
Log.Warning("未检测到导航相机");
_cameraError = "未检测到导航相机,请检查连接坎針坯软件。";
_cameraError = "未检测到导航相机,请检查连接后重启软件。";
}
catch (Exception ex)
{
@@ -550,7 +546,7 @@ namespace XplorePlane
}
/// <summary>
/// 模块已在 CreateShell 中杝剝初始化,此处跳过靿兝針夝加载
/// 模块已在 CreateShell 中提前初始化,此处跳过避免重复加载
/// </summary>
protected override void InitializeModules()
{
@@ -566,7 +562,7 @@ namespace XplorePlane
// 注册 Serilog 的 ILogger 实例
containerRegistry.RegisterInstance<ILogger>(Log.Logger);
// 注册 XP.Common.ILoggerService 适
// 注册 XP.Common.ILoggerService 适
containerRegistry.RegisterSingleton<ILoggerService, SerilogLoggerService>();
// 注册视图和视图模型
@@ -575,44 +571,44 @@ namespace XplorePlane
containerRegistry.RegisterSingleton<ViewportPanelViewModel>();
containerRegistry.RegisterSingleton<NavigationPropertyPanelViewModel>();
// 注册图僝处睆朝务与视图
// 注册图像处理服务与视图
containerRegistry.RegisterSingleton<IImageProcessingService, ImageProcessingService>();
containerRegistry.Register<ImageProcessingViewModel>();
// 注册水线务(例,共享 IImageProcessingService
// 注册水线务(例,共享 IImageProcessingService
containerRegistry.RegisterSingleton<IPipelineExecutionService, PipelineExecutionService>();
containerRegistry.RegisterSingleton<IPipelinePersistenceService, PipelinePersistenceService>();
// 注册全局状思朝务(例)
// 注册全局状态服务(例)
containerRegistry.RegisterSingleton<IAppStateService, AppStateService>();
containerRegistry.RegisterSingleton<IXpDataPathService, XpDataPathService>();
containerRegistry.RegisterSingleton<IDebugPanelConfigService, DebugPanelConfigService>();
containerRegistry.Register<DebugPanelViewModel>();
containerRegistry.Register<DebugPanelWindow>();
// 注册检测酝方朝务(例)
// 注册检测配方服务(例)
containerRegistry.RegisterSingleton<IRecipeService, RecipeService>();
// 注册水线 ViewModel次解创建新实例)
// 注册水线 ViewModel次解创建新实例)
containerRegistry.Register<PipelineEditorViewModel>();
containerRegistry.Register<OperatorToolboxViewModel>();
// 注册硬件库的 ViewModel(供 ViewModelLocator 自动装
// 注册硬件库的 ViewModel(供 ViewModelLocator 自动装
containerRegistry.Register<XP.Hardware.RaySource.ViewModels.RaySourceOperateViewModel>();
// 注册 SQLite 置和数库上下文(FilamentLifetimeService 依赖)
// 注册 SQLite 置和数库上下文(FilamentLifetimeService 依赖)
var sqliteConfig = DatabaseConfigLoader.LoadSqliteConfig();
containerRegistry.RegisterInstance(sqliteConfig);
containerRegistry.RegisterSingleton<IDbContext, SqliteContext>();
// 注册通用模块的务(本地化Dump
// 注册通用模块的务(本地化Dump
containerRegistry.RegisterSingleton<ILocalizationConfig, LocalizationConfig>();
containerRegistry.RegisterSingleton<ILocalizationService, ResxLocalizationService>();
containerRegistry.RegisterSingleton<DumpConfig>(() => DumpConfigLoader.LoadDumpConfig());
containerRegistry.RegisterSingleton<IDumpService, DumpService>();
// ── CNC / 矩阵编排 / 测針数杮朝务(例)──
// ── CNC / 矩阵编排 / 测量数据服务(例)──
containerRegistry.RegisterSingleton<ICncProgramService, CncProgramService>();
containerRegistry.RegisterSingleton<IMatrixService, MatrixService>();
containerRegistry.RegisterSingleton<IMeasurementDataService, MeasurementDataService>();
@@ -620,11 +616,11 @@ namespace XplorePlane
containerRegistry.RegisterSingleton<IImagePersistenceService, ImagePersistenceService>();
containerRegistry.RegisterSingleton<ICncExecutionService, CncExecutionService>();
// ── 主界面实时图 / 探测器队列务(例)──
// ── 主界面实时图 / 探测器队列务(例)──
containerRegistry.RegisterSingleton<IMainViewportService, MainViewportService>();
containerRegistry.RegisterSingleton<IDetectorFramePipelineService, DetectorFramePipelineService>();
// ── CNC / 矩阵 ViewModel(瞬)──
// ── CNC / 矩阵 ViewModel(瞬)──
containerRegistry.Register<CncEditorViewModel>();
containerRegistry.Register<MatrixEditorViewModel>();
containerRegistry.Register<MeasurementStatsViewModel>();
@@ -635,21 +631,21 @@ namespace XplorePlane
containerRegistry.RegisterForNavigation<MatrixPageView>();
containerRegistry.Register<InspectionReportViewerWindow>();
// ── 导航相机务(例)──
// ── 导航相机务(例)──
containerRegistry.RegisterSingleton<ICameraFactory, CameraFactory>();
containerRegistry.RegisterSingleton<ICameraController>(() =>
new CameraFactory().CreateController("Basler"));
containerRegistry.RegisterSingleton<ICameraService, CameraService>();
// ── 录制务(例)──
// ── 录制务(例)──
containerRegistry.RegisterSingleton<IViewportRecordingService, ViewportRecordingService>();
Log.Information("依赖注入容器置完");
Log.Information("依赖注入容器置完");
}
protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
{
// 所有模块务已在 RegisterTypes 中手动注册
// 所有模块务已在 RegisterTypes 中手动注册
// CommonModule: ILocalizationService, IDumpService
// RaySourceModule: IRaySourceService, IRaySourceFactory, IFilamentLifetimeService