# 授权服务使用指南 | License Service Usage Guide ## 概述 | Overview XplorePlane 通过 `XP.Common.License` 命名空间下的 `ILicenseService` 提供统一的授权管理。底层基于海克斯康 CLMS(Computational License Management System)SDK,使用 `MORCODE.dll` 进行许可证校验。 ## 产品授权信息 | Product License Information | 项目 | 值 | | --- | --- | | CLMS 模块 ID(Module ID) | `4` | | 零件号(Part Number) | `LS950-0071-5-1` | `Module ID` 是 CLMS 在 SDK 中标识本产品的唯一编号,调用 `CLM_ModuleIsLicensed` 时必须传入此值;`Part Number` 是产品在 CLMS 许可发行系统中的物料编号,用于申请、签发、续期许可证。 ## 授权模式 | License Modes `LicenseMode` 枚举定义见 `XP.Common.License.Enums.LicenseMode`: | 模式 | 枚举值 | 数值 | 说明 | | --- | --- | --- | --- | | CLMS 正式授权 | `Clms` | `0` | 通过 CLMS SDK 进行完整授权校验,包含登录、许可范围、模块、SMA、到期日期等检查 | | 临时测试模式 | `TemporaryTest` | `885` | 不调用 CLMS SDK,直接放行 15 分钟,用于研发/测试场景 | ## 配置项 | Configuration Items 授权配置位于主应用 `App.config` 中,键前缀为 `License:`,对应 `XP.Common.License.Configs.LicenseConfig`: ```xml ``` | 键 | 类型 | 默认值 | 有效值 | 说明 | | --- | --- | --- | --- | --- | | `License:LicenseMode` | int | `0` | `0`、`885` | 授权模式 | | `License:ModuleId` | ushort | `4` | `1` ~ `65535` | CLMS 模块 ID | | `License:UseSma` | bool | `false` | `true`、`false` | 是否启用 SMA(软件维护协议)校验 | | `License:LicenseState` | int | `20` | `10`、`20` | 上次运行时的授权结果,由服务自动维护 | > 配置中无效或缺失的键会回退到默认值,详见 `XP.Common.License.Configs.ConfigLoader`。 ## 正式授权流程 | Formal Authorization Flow `LicenseMode = 0`(`Clms`)时,`LicenseService.CheckAuthorization()` 依次执行以下步骤: 1. **系统时间检查**(可选):调用 `CLM_CheckSystemTime`,老版本 SDK 缺失此入口点时跳过。 2. **登录验证**:调用 `CLM_Login`(核心步骤,必须存在)。 3. **许可范围检查**:调用 `CLM_Login_Scope`(核心步骤)。 4. **SMA 验证**(可选):仅当 `License:UseSma = true` 时执行。比较 SMA 年份/季度与当前软件主版本号/次版本号,季度不匹配会判定失败。 5. **浮动许可信息**(可选):通过 `CLM_GetIP` 获取 IP 与端口。 6. **错误信息读取**(可选):通过 `CLM_GetError` 拉取 SDK 端错误描述。 7. **模块授权检查**:调用 `CLM_ModuleIsLicensed`,传入 `Module ID = 4`。 8. **到期日期获取**:调用 `CLM_GetWarrantyExpiration`,剩余 ≤ 30 天时记录警告。 任意核心步骤失败即视为授权失败,写回 `License:LicenseState = 20`,主应用弹窗提示并退出。 ## 临时测试模式 | Temporary Test Mode `LicenseMode = 885`(`TemporaryTest`)用于跳过 CLMS 校验,便于离线开发和功能演示。 ### 行为 | Behavior - 不加载 `MORCODE.dll`,不调用任何 CLMS API,授权直接通过。 - 启动后立刻开启 15 分钟(900 秒)倒计时,到期触发 `TestModeTimeout` 事件,主应用应执行优雅关闭。 - 倒计时途中分别在剩余 5 分钟、1 分钟时触发 `TestModeWarning5Min`、`TestModeWarning1Min` 事件用于提醒。 - 上述三个事件只在临时测试模式下被触发,正式授权(`Clms`)下不会创建计时器。 ### 启用方式 | How to Enable 修改主应用 `App.config`: ```xml ``` 启动后将看到提示:「当前为临时测试模式,软件将在 15 分钟后自动关闭」。 > **注意**:临时测试模式仅用于研发与内部测试场景,**禁止用于生产或交付**。发布前请务必将 `License:LicenseMode` 还原为 `0`。 ## 使用示例 | Usage Examples ### 注入并校验 | Inject and Verify ```csharp using XP.Common.License.Interfaces; using XP.Common.License.Enums; public class StartupChecker { private readonly ILicenseService _licenseService; private readonly ILoggerService _logger; public StartupChecker(ILicenseService licenseService, ILoggerService logger) { _licenseService = licenseService ?? throw new ArgumentNullException(nameof(licenseService)); _logger = logger?.ForModule() ?? throw new ArgumentNullException(nameof(logger)); } public bool Run() { var result = _licenseService.CheckAuthorization(); if (!result.IsAuthorized) { _logger.Error(null, "授权失败:{Message} | License failed: {Message}", result.Message); return false; } // 仅在临时测试模式下订阅倒计时事件 | Subscribe countdown events only in test mode if (_licenseService.LicenseMode == LicenseMode.TemporaryTest) { _licenseService.TestModeWarning5Min += (s, e) => _logger.Warn("临时测试模式剩余 5 分钟"); _licenseService.TestModeWarning1Min += (s, e) => _logger.Warn("临时测试模式剩余 1 分钟"); _licenseService.TestModeTimeout += (s, e) => Application.Current.Shutdown(); } return true; } } ``` ### 检查特定模块授权 | Check Module Authorization ```csharp const ushort XplorePlaneModuleId = 4; if (!_licenseService.IsModuleLicensed(XplorePlaneModuleId)) { _logger.Warn("模块 {ModuleId} 未授权 | Module {ModuleId} not licensed", XplorePlaneModuleId); } ``` ### 读取授权信息 | Read License Information ```csharp DateTime? expiration = _licenseService.GetExpirationDate(); // 授权到期日期 DateTime? sma = _licenseService.GetSmaDate(); // SMA 到期日期 int remaining = _licenseService.GetRemainingTestTime(); // 临时测试剩余秒数;非测试模式返回 -1 ``` ## 接口与事件 | Interface & Events `ILicenseService` 提供以下成员(详见 `XP.Common.License.Interfaces.ILicenseService`): - `LicenseCheckResult CheckAuthorization()`:执行完整授权校验。 - `bool IsAuthorized`:当前会话是否已授权。 - `LicenseMode LicenseMode`:当前授权模式。 - `DateTime? GetExpirationDate()`:授权到期日期。 - `DateTime? GetSmaDate()`:SMA 到期日期。 - `bool IsModuleLicensed(ushort moduleId)`:检查指定模块是否被授权。 - `int GetRemainingTestTime()`:临时测试模式剩余秒数。 - 事件:`TestModeWarning5Min`、`TestModeWarning1Min`、`TestModeTimeout`。 ## 常见问题 | FAQ ### 1. 启动时提示 `MORCODE.dll 加载失败` | `Failed to load MORCODE.dll` 确认 `MORCODE.dll` 已随 `ReleaseFiles` 一同部署,并位于主程序同级目录。研发阶段可临时切换到临时测试模式绕过。 ### 2. 提示「模块号码 4 不可用」| `Module 4 unavailable` CLMS 服务器签发的许可证未包含 `Module ID = 4`(零件号 `LS950-0071-5-1`)。请联系海克斯康许可团队确认许可范围。 ### 3. SMA 校验失败 | SMA validation failed SMA 年份必须 ≥ 软件主版本号;同年时 SMA 季度必须 ≥ 软件次版本号。若需临时绕过,可将 `License:UseSma` 设为 `false`,但发布版本仍应保持 SMA 校验启用。 ### 4. 授权成功后是否还有倒计时?| Will the countdown still trigger after a successful formal authorization? 不会。倒计时仅在 `LicenseMode = TemporaryTest` 时启动,`Clms` 正式授权下三个事件永远不会被触发。 ## 相关文件 | Related Files - `XP.Common/License/Interfaces/ILicenseService.cs` — 服务接口 - `XP.Common/License/Implementations/LicenseService.cs` — 服务实现 - `XP.Common/License/Configs/LicenseConfig.cs` — 配置实体 - `XP.Common/License/Configs/ConfigLoader.cs` — 配置加载器 - `XP.Common/License/Enums/LicenseMode.cs` — 授权模式枚举 - `XP.Common/License/Enums/LicenseState.cs` — 授权状态枚举 - `XP.Common/License/Native/NativeMethods.cs` — CLMS SDK P/Invoke 封装 - `XplorePlane/App.xaml.cs` — 主应用启动时调用 `PerformLicenseCheck()` 的入口