# 探测器模块使用指南 | Detector Module Usage Guide ## 1. 模块概述 | Module Overview XP.Hardware.Detector 是 XplorePlane X 射线检测系统的探测器控制模块,负责与工业 X 射线探测器进行通讯和控制。该模块采用策略模式设计,支持多种探测器型号的统一管理。 ### 核心特性 | Key Features - 支持多种探测器型号(Varex、iRay 等) - 完整的探测器生命周期管理(初始化、采集、校正) - 单帧和连续采集模式 - 自动校正功能(暗场、增益、坏像素) - 实时状态监控 - 基于 Prism 事件聚合器的松耦合通讯 - 异步操作,不阻塞 UI 线程 --- ## 2. 模块注册 | Module Registration 探测器模块通过 Prism 的模块化系统注册,在应用启动时自动加载。 ### 在 App.xaml.cs 中注册 ```csharp using Prism.Modularity; using XP.Hardware.Detector.Module; protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog) { // 注册探测器模块 | Register Detector module moduleCatalog.AddModule(); base.ConfigureModuleCatalog(moduleCatalog); } ``` ### 模块自动注册的服务 - `IDetectorFactory` - 探测器工厂(瞬态) - `IDetectorService` - 探测器业务服务(单例) --- ## 3. 配置文件设置 | Configuration File Setup 在 `App.config` 中添加探测器配置: ```xml ``` ### 配置参数说明 | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | Type | string | Varex | 探测器类型(Varex/IRay)| | IP | string | 192.168.1.200 | 探测器 IP 地址 | | Port | int | 50000 | 探测器端口号 | | SavePath | string | D:\Images | 图像存储路径 | | AutoSave | bool | true | 是否自动保存图像 | --- ## 4. 在 ViewModel 中使用 | Usage in ViewModel ### 4.1 注入服务 ```csharp using Prism.Commands; using Prism.Events; using Prism.Mvvm; using System.Threading.Tasks; using XP.Common.Logging.Interfaces; using XP.Hardware.Detector.Abstractions; using XP.Hardware.Detector.Abstractions.Enums; using XP.Hardware.Detector.Abstractions.Events; using XP.Hardware.Detector.Services; namespace YourNamespace.ViewModels { public class YourViewModel : BindableBase { private readonly IDetectorService _detectorService; private readonly IEventAggregator _eventAggregator; private readonly ILoggerService _logger; /// /// 构造函数,通过依赖注入获取服务 | Constructor with dependency injection /// public YourViewModel( IDetectorService detectorService, IEventAggregator eventAggregator, ILoggerService logger) { _detectorService = detectorService; _eventAggregator = eventAggregator; _logger = logger.ForModule("YourViewModel"); // 订阅事件 | Subscribe to events SubscribeEvents(); } private void SubscribeEvents() { // 订阅图像采集事件 | Subscribe to image captured event _eventAggregator.GetEvent() .Subscribe(OnImageCaptured); // 订阅校正完成事件 | Subscribe to correction completed event _eventAggregator.GetEvent() .Subscribe(OnCorrectionCompleted); } private void OnImageCaptured(ImageCapturedEventArgs args) { _logger.Info($"图像已采集: {args.FrameNumber}"); } private void OnCorrectionCompleted(CorrectionCompletedEventArgs args) { _logger.Info($"校正完成: {args.CorrectionType}"); } } } ``` ### 4.2 初始化探测器 ```csharp /// /// 初始化探测器 | Initialize detector /// public async Task InitializeDetectorAsync() { try { _logger.Info("开始初始化探测器... | Starting detector initialization..."); StatusMessage = "正在初始化... | Initializing..."; DetectorResult result = await _detectorService.InitializeAsync(); if (result.IsSuccess) { _logger.Info("探测器初始化成功 | Detector initialized successfully"); StatusMessage = "探测器已就绪 | Detector ready"; // 获取探测器信息 | Get detector information DetectorInfo info = _detectorService.GetInfo(); _logger.Info($"探测器型号: {info.Model}, 分辨率: {info.MaxWidth}x{info.MaxHeight}"); } else { _logger.Error(null, $"探测器初始化失败: {result.ErrorMessage}"); StatusMessage = $"初始化失败: {result.ErrorMessage}"; } } catch (Exception ex) { _logger.Error(ex, $"初始化异常: {ex.Message}"); StatusMessage = $"初始化异常: {ex.Message}"; } } ``` ### 4.3 单帧采集 ```csharp /// /// 单帧采集 | Single frame acquisition /// public async Task AcquireSingleFrameAsync() { try { if (_detectorService.Status != DetectorStatus.Ready) { _logger.Warn("探测器未就绪,无法采集"); StatusMessage = "探测器未就绪 | Detector not ready"; return; } _logger.Info("开始单帧采集... | Starting single frame acquisition..."); StatusMessage = "正在采集... | Acquiring..."; DetectorResult result = await _detectorService.AcquireSingleFrameAsync(); if (result.IsSuccess) { _logger.Info("单帧采集成功 | Single frame acquired successfully"); StatusMessage = "采集完成 | Acquisition completed"; } else { _logger.Error(null, $"单帧采集失败: {result.ErrorMessage}"); StatusMessage = $"采集失败: {result.ErrorMessage}"; } } catch (Exception ex) { _logger.Error(ex, $"单帧采集异常: {ex.Message}"); StatusMessage = $"采集异常: {ex.Message}"; } } ``` ### 4.4 启动连续采集 ```csharp /// /// 启动连续采集 | Start continuous acquisition /// public async Task StartAcquisitionAsync() { try { if (_detectorService.Status != DetectorStatus.Ready) { _logger.Warn("探测器未就绪,无法启动采集"); return; } _logger.Info("启动连续采集... | Starting continuous acquisition..."); StatusMessage = "连续采集中... | Continuous acquisition..."; DetectorResult result = await _detectorService.StartAcquisitionAsync(); if (result.IsSuccess) { _logger.Info("连续采集已启动 | Continuous acquisition started"); IsAcquiring = true; } else { _logger.Error(null, $"启动采集失败: {result.ErrorMessage}"); StatusMessage = $"启动失败: {result.ErrorMessage}"; } } catch (Exception ex) { _logger.Error(ex, $"启动采集异常: {ex.Message}"); StatusMessage = $"启动异常: {ex.Message}"; } } ``` ### 4.5 停止采集 ```csharp /// /// 停止采集 | Stop acquisition /// public async Task StopAcquisitionAsync() { try { _logger.Info("停止采集... | Stopping acquisition..."); StatusMessage = "正在停止... | Stopping..."; DetectorResult result = await _detectorService.StopAcquisitionAsync(); if (result.IsSuccess) { _logger.Info("采集已停止 | Acquisition stopped"); StatusMessage = "已停止 | Stopped"; IsAcquiring = false; } else { _logger.Error(null, $"停止采集失败: {result.ErrorMessage}"); StatusMessage = $"停止失败: {result.ErrorMessage}"; } } catch (Exception ex) { _logger.Error(ex, $"停止采集异常: {ex.Message}"); StatusMessage = $"停止异常: {ex.Message}"; } } ``` --- ## 5. 校正功能 | Correction Functions ### 5.1 自动校正 ```csharp /// /// 执行自动校正(暗场+增益+坏像素)| Execute auto correction (dark + gain + bad pixel) /// /// 采集帧数 | Frame count public async Task AutoCorrectionAsync(int frameCount = 10) { try { _logger.Info($"开始自动校正,帧数: {frameCount} | Starting auto correction, frames: {frameCount}"); StatusMessage = "正在校正... | Correcting..."; DetectorResult result = await _detectorService.AutoCorrectionAsync(frameCount); if (result.IsSuccess) { _logger.Info("自动校正完成 | Auto correction completed"); StatusMessage = "校正完成 | Correction completed"; } else { _logger.Error(null, $"自动校正失败: {result.ErrorMessage}"); StatusMessage = $"校正失败: {result.ErrorMessage}"; } } catch (Exception ex) { _logger.Error(ex, $"自动校正异常: {ex.Message}"); StatusMessage = $"校正异常: {ex.Message}"; } } ``` ### 5.2 获取探测器信息 ```csharp /// /// 获取探测器信息 | Get detector information /// public void GetDetectorInfo() { try { DetectorInfo info = _detectorService.GetInfo(); if (info != null) { _logger.Info($"探测器信息:"); _logger.Info($" 型号: {info.Model}"); _logger.Info($" 序列号: {info.SerialNumber}"); _logger.Info($" 固件版本: {info.FirmwareVersion}"); _logger.Info($" 分辨率: {info.MaxWidth}x{info.MaxHeight}"); _logger.Info($" 像素尺寸: {info.PixelSize}μm"); _logger.Info($" 位深度: {info.BitDepth}bit"); // 更新 UI 显示 | Update UI display DetectorModel = info.Model; Resolution = $"{info.MaxWidth}x{info.MaxHeight}"; PixelSize = $"{info.PixelSize}μm"; } } catch (Exception ex) { _logger.Error(ex, $"获取探测器信息异常: {ex.Message}"); } } ``` --- ## 6. Prism 事件通讯 | Prism Event Communication 模块使用 Prism 事件聚合器实现跨模块通讯,支持以下事件: ### 6.1 图像采集事件 ```csharp // 订阅图像采集事件 | Subscribe to image captured event _eventAggregator.GetEvent() .Subscribe(OnImageCaptured, ThreadOption.UIThread); private void OnImageCaptured(ImageCapturedEventArgs args) { // args.FrameNumber - 帧编号 // args.Timestamp - 时间戳 // args.ImageData - 图像数据(如果有) FrameNumber = args.FrameNumber; LastCaptureTime = args.Timestamp; _logger.Info($"图像已采集: 帧 {args.FrameNumber}"); } ``` ### 6.2 校正完成事件 ```csharp // 订阅校正完成事件 | Subscribe to correction completed event _eventAggregator.GetEvent() .Subscribe(OnCorrectionCompleted, ThreadOption.UIThread); private void OnCorrectionCompleted(CorrectionCompletedEventArgs args) { // args.CorrectionType - 校正类型(暗场/增益/坏像素) // args.IsSuccess - 是否成功 // args.Message - 消息 if (args.IsSuccess) { _logger.Info($"校正完成: {args.CorrectionType}"); StatusMessage = $"{args.CorrectionType} 校正完成"; } else { _logger.Error(null, $"校正失败: {args.Message}"); StatusMessage = $"校正失败: {args.Message}"; } } ``` --- ## 7. 完整示例 | Complete Example ```csharp using Prism.Commands; using Prism.Events; using Prism.Mvvm; using System; using System.Threading.Tasks; using System.Windows.Input; using XP.Common.Logging.Interfaces; using XP.Hardware.Detector.Abstractions; using XP.Hardware.Detector.Abstractions.Enums; using XP.Hardware.Detector.Abstractions.Events; using XP.Hardware.Detector.Services; namespace YourNamespace.ViewModels { public class DetectorControlViewModel : BindableBase { private readonly IDetectorService _detectorService; private readonly IEventAggregator _eventAggregator; private readonly ILoggerService _logger; #region 属性 | Properties private string _statusMessage; public string StatusMessage { get => _statusMessage; set => SetProperty(ref _statusMessage, value); } private DetectorStatus _detectorStatus; public DetectorStatus DetectorStatus { get => _detectorStatus; set => SetProperty(ref _detectorStatus, value); } private bool _isAcquiring; public bool IsAcquiring { get => _isAcquiring; set => SetProperty(ref _isAcquiring, value); } private int _frameNumber; public int FrameNumber { get => _frameNumber; set => SetProperty(ref _frameNumber, value); } private string _detectorModel; public string DetectorModel { get => _detectorModel; set => SetProperty(ref _detectorModel, value); } private string _resolution; public string Resolution { get => _resolution; set => SetProperty(ref _resolution, value); } #endregion #region 命令 | Commands public ICommand InitializeCommand { get; } public ICommand AcquireSingleFrameCommand { get; } public ICommand StartAcquisitionCommand { get; } public ICommand StopAcquisitionCommand { get; } public ICommand AutoCorrectionCommand { get; } public ICommand GetInfoCommand { get; } #endregion public DetectorControlViewModel( IDetectorService detectorService, IEventAggregator eventAggregator, ILoggerService logger) { _detectorService = detectorService; _eventAggregator = eventAggregator; _logger = logger.ForModule("DetectorControlViewModel"); // 初始化命令 | Initialize commands InitializeCommand = new DelegateCommand(async () => await InitializeAsync()); AcquireSingleFrameCommand = new DelegateCommand(async () => await AcquireSingleFrameAsync(), CanAcquire) .ObservesProperty(() => DetectorStatus); StartAcquisitionCommand = new DelegateCommand(async () => await StartAcquisitionAsync(), CanStartAcquisition) .ObservesProperty(() => DetectorStatus) .ObservesProperty(() => IsAcquiring); StopAcquisitionCommand = new DelegateCommand(async () => await StopAcquisitionAsync(), CanStopAcquisition) .ObservesProperty(() => IsAcquiring); AutoCorrectionCommand = new DelegateCommand(async () => await AutoCorrectionAsync(), CanCorrect) .ObservesProperty(() => DetectorStatus); GetInfoCommand = new DelegateCommand(GetInfo); // 订阅事件 | Subscribe to events SubscribeEvents(); } #region 命令实现 | Command Implementations private async Task InitializeAsync() { try { StatusMessage = "正在初始化... | Initializing..."; DetectorResult result = await _detectorService.InitializeAsync(); if (result.IsSuccess) { DetectorStatus = _detectorService.Status; StatusMessage = "探测器已就绪 | Detector ready"; GetInfo(); } else { StatusMessage = $"初始化失败: {result.ErrorMessage}"; } } catch (Exception ex) { _logger.Error(ex, "初始化异常"); StatusMessage = $"初始化异常: {ex.Message}"; } } private async Task AcquireSingleFrameAsync() { try { StatusMessage = "正在采集... | Acquiring..."; DetectorResult result = await _detectorService.AcquireSingleFrameAsync(); if (result.IsSuccess) { StatusMessage = "采集完成 | Acquisition completed"; } else { StatusMessage = $"采集失败: {result.ErrorMessage}"; } } catch (Exception ex) { _logger.Error(ex, "单帧采集异常"); StatusMessage = $"采集异常: {ex.Message}"; } } private async Task StartAcquisitionAsync() { try { StatusMessage = "启动连续采集... | Starting continuous acquisition..."; DetectorResult result = await _detectorService.StartAcquisitionAsync(); if (result.IsSuccess) { IsAcquiring = true; DetectorStatus = _detectorService.Status; StatusMessage = "连续采集中... | Continuous acquisition..."; } else { StatusMessage = $"启动失败: {result.ErrorMessage}"; } } catch (Exception ex) { _logger.Error(ex, "启动采集异常"); StatusMessage = $"启动异常: {ex.Message}"; } } private async Task StopAcquisitionAsync() { try { StatusMessage = "正在停止... | Stopping..."; DetectorResult result = await _detectorService.StopAcquisitionAsync(); if (result.IsSuccess) { IsAcquiring = false; DetectorStatus = _detectorService.Status; StatusMessage = "已停止 | Stopped"; } else { StatusMessage = $"停止失败: {result.ErrorMessage}"; } } catch (Exception ex) { _logger.Error(ex, "停止采集异常"); StatusMessage = $"停止异常: {ex.Message}"; } } private async Task AutoCorrectionAsync() { try { StatusMessage = "正在校正... | Correcting..."; DetectorResult result = await _detectorService.AutoCorrectionAsync(10); if (result.IsSuccess) { StatusMessage = "校正完成 | Correction completed"; } else { StatusMessage = $"校正失败: {result.ErrorMessage}"; } } catch (Exception ex) { _logger.Error(ex, "自动校正异常"); StatusMessage = $"校正异常: {ex.Message}"; } } private void GetInfo() { try { DetectorInfo info = _detectorService.GetInfo(); if (info != null) { DetectorModel = info.Model; Resolution = $"{info.MaxWidth}x{info.MaxHeight}"; } } catch (Exception ex) { _logger.Error(ex, "获取信息异常"); } } #endregion #region 命令条件 | Command Conditions private bool CanAcquire() => DetectorStatus == DetectorStatus.Ready; private bool CanStartAcquisition() => DetectorStatus == DetectorStatus.Ready && !IsAcquiring; private bool CanStopAcquisition() => IsAcquiring; private bool CanCorrect() => DetectorStatus == DetectorStatus.Ready; #endregion #region 事件处理 | Event Handlers private void SubscribeEvents() { _eventAggregator.GetEvent() .Subscribe(OnImageCaptured, ThreadOption.UIThread); _eventAggregator.GetEvent() .Subscribe(OnCorrectionCompleted, ThreadOption.UIThread); } private void OnImageCaptured(ImageCapturedEventArgs args) { FrameNumber = args.FrameNumber; } private void OnCorrectionCompleted(CorrectionCompletedEventArgs args) { if (args.IsSuccess) { StatusMessage = $"{args.CorrectionType} 校正完成"; } } #endregion } } ``` --- ## 8. 在应用退出时释放资源 | Release Resources on Application Exit 在 `App.xaml.cs` 的 `OnExit` 方法中添加: ```csharp protected override void OnExit(ExitEventArgs e) { // 记录应用退出日志 | Log application exit Log.Information("XplorePlane主应用退出(XP.App-OnExit)"); // 释放探测器资源 | Release detector resources try { var detectorService = Container.Resolve(); // 探测器服务会在 Dispose 时自动停止采集和释放资源 // Detector service will automatically stop acquisition and release resources on Dispose Log.Information("探测器资源已成功释放 | Detector resources released successfully"); } catch (Exception ex) { Log.Error(ex, "探测器资源释放失败,忽略该错误继续退出 | Failed to release detector resources"); } // 释放其他资源... | Release other resources... // 释放Serilog资源(避免日志丢失)| Release Serilog resources Log.CloseAndFlush(); base.OnExit(e); } ``` --- ## 9. 探测器状态 | Detector Status ### 9.1 状态枚举 ```csharp public enum DetectorStatus { Uninitialized = 0, // 未初始化 Initializing = 1, // 初始化中 Ready = 2, // 就绪 Acquiring = 3, // 采集中 Correcting = 4, // 校正中 Error = 5 // 错误 } ``` ### 9.2 状态监控 ```csharp // 监控探测器状态变化 | Monitor detector status changes private void MonitorStatus() { DetectorStatus currentStatus = _detectorService.Status; switch (currentStatus) { case DetectorStatus.Uninitialized: StatusMessage = "未初始化 | Uninitialized"; break; case DetectorStatus.Initializing: StatusMessage = "初始化中... | Initializing..."; break; case DetectorStatus.Ready: StatusMessage = "就绪 | Ready"; break; case DetectorStatus.Acquiring: StatusMessage = "采集中... | Acquiring..."; break; case DetectorStatus.Correcting: StatusMessage = "校正中... | Correcting..."; break; case DetectorStatus.Error: StatusMessage = "错误 | Error"; // 获取错误信息 | Get error information DetectorResult error = _detectorService.GetLastError(); _logger.Error(null, $"探测器错误: {error.ErrorMessage}"); break; } } ``` --- ## 10. 异常处理 | Exception Handling ### 10.1 DetectorResult 结果处理 所有操作返回 `DetectorResult` 对象: ```csharp DetectorResult result = await _detectorService.InitializeAsync(); if (result.IsSuccess) { // 操作成功 | Operation successful _logger.Info("操作成功"); } else { // 操作失败 | Operation failed string error = result.ErrorMessage; int errorCode = result.ErrorCode; Exception exception = result.Exception; _logger.Error(exception, $"操作失败: {error}, 错误码: {errorCode}"); } ``` ### 10.2 异常捕获 ```csharp try { DetectorResult result = await _detectorService.AcquireSingleFrameAsync(); // 处理结果 | Process result } catch (TimeoutException ex) { // 超时异常 | Timeout exception _logger.Error(ex, "操作超时"); MessageBox.Show("操作超时,请检查探测器连接", "超时", MessageBoxButton.OK, MessageBoxImage.Warning); } catch (InvalidOperationException ex) { // 无效操作异常 | Invalid operation exception _logger.Error(ex, "无效操作"); MessageBox.Show($"无效操作: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } catch (Exception ex) { // 其他异常 | Other exceptions _logger.Error(ex, "未知错误"); MessageBox.Show($"发生错误: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); } ``` --- ## 11. 日志记录 | Logging 模块使用 Serilog 进行结构化日志记录: ### 11.1 日志级别 - **Debug**: 详细的调试信息(帧采集、状态变化等) - **Info**: 一般信息(初始化成功、采集开始等) - **Warn**: 警告信息(状态异常、参数警告等) - **Error**: 错误信息(操作失败、通讯异常等) - **Fatal**: 致命错误(系统崩溃等) ### 11.2 日志示例 ```csharp // 信息日志 | Info log _logger.Info("探测器初始化成功 | Detector initialized successfully"); // 警告日志 | Warning log _logger.Warn("探测器未就绪 | Detector not ready"); // 错误日志 | Error log _logger.Error(ex, $"操作失败: {ex.Message} | Operation failed: {ex.Message}"); // 调试日志 | Debug log _logger.Debug($"采集帧 {frameNumber} | Acquired frame {frameNumber}"); ``` --- ## 12. 性能优化建议 | Performance Optimization Suggestions ### 12.1 图像处理 避免在 UI 线程处理大图像: ```csharp // 推荐:在后台线程处理图像 | Recommended: Process images in background thread await Task.Run(() => { // 图像处理逻辑 | Image processing logic ProcessImage(imageData); }); ``` ### 12.2 异步操作 所有 I/O 操作使用异步方法: ```csharp // 正确:异步操作 | Correct: Async operation await _detectorService.AcquireSingleFrameAsync(); // 错误:同步阻塞 | Wrong: Synchronous blocking _detectorService.AcquireSingleFrameAsync().Wait(); // 不要这样做! ``` ### 12.3 事件订阅 及时取消不再需要的事件订阅: ```csharp // 保存订阅令牌 | Save subscription token private SubscriptionToken _imageCapturedToken; // 订阅事件 | Subscribe to event _imageCapturedToken = _eventAggregator.GetEvent() .Subscribe(OnImageCaptured, ThreadOption.UIThread); // 取消订阅 | Unsubscribe _eventAggregator.GetEvent() .Unsubscribe(_imageCapturedToken); ``` --- ## 13. 故障排查 | Troubleshooting ### 13.1 初始化失败 **问题**: 探测器初始化失败 **可能原因**: - 探测器 IP 地址或端口配置错误 - 探测器未启动或网络不通 - 探测器驱动未正确安装 - 配置文件参数错误 **解决方案**: 1. 检查 `App.config` 中的探测器连接参数 2. 使用 `ping` 命令测试探测器网络连接 3. 确认探测器驱动和 SDK 已安装 4. 查看日志文件获取详细错误信息 ### 13.2 采集失败 **问题**: 无法采集图像 **可能原因**: - 探测器未初始化 - 探测器处于错误状态 - 校正未完成 - 网络通讯异常 **解决方案**: 1. 确认已调用 `InitializeAsync()` 并成功 2. 检查探测器状态是否为 `Ready` 3. 执行自动校正 `AutoCorrectionAsync()` 4. 检查网络连接和通讯日志 ### 13.3 校正失败 **问题**: 校正操作失败 **可能原因**: - 探测器未就绪 - 射线源未开启(增益校正需要) - 采集帧数不足 - 环境光干扰 **解决方案**: 1. 确认探测器状态为 `Ready` 2. 增益校正前确保射线源已开启 3. 增加采集帧数(建议 10 帧以上) 4. 检查暗场环境,避免光线干扰 ### 13.4 通讯超时 **问题**: 操作超时 **可能原因**: - 网络延迟过高 - 探测器响应慢 - 超时配置过短 **解决方案**: 1. 检查网络连接质量 2. 增加配置文件中的超时时间 3. 检查探测器负载情况 --- ## 14. 注意事项 | Notes 1. **线程安全**: `IDetectorService` 是单例,多个 ViewModel 共享同一个实例 2. **异步操作**: 所有操作都是异步的,避免阻塞 UI 线程 3. **状态检查**: 操作前检查探测器状态,确保处于正确状态 4. **资源释放**: 应用退出时探测器会自动停止采集并释放资源 5. **事件订阅**: 记得在 ViewModel 销毁时取消事件订阅 6. **校正顺序**: 建议按照暗场→增益→坏像素的顺序进行校正 7. **日志记录**: 所有关键操作都有详细的日志记录 8. **错误处理**: 始终检查 `DetectorResult.IsSuccess` 并处理错误 --- ## 15. 文档索引 | Documentation Index - **[GUIDENCE.md](./GUIDENCE.md)** - 本文档,详细使用指南 - **[README.md](./README.md)** - 项目概述和快速参考 - **[App.config.example](./App.config.example)** - 配置文件示例 --- ## 16. 技术支持 | Technical Support 如有问题或建议,请联系项目维护团队。 --- **最后更新 | Last Updated**: 2026-03-11