C#替换预处理器指令实现单安装包适配双许可模式方案咨询
单安装包动态许可切换实现方案
1 预处理器逻辑改写为运行时判断的C#代码
核心思路是把编译期分支改为运行时基于许可证文件的判断,步骤如下:
- 第一步:定义许可类型枚举,封装DAT许可证读取、校验逻辑
- 第二步:删除原
#if TRAIL/#elif LICENSED预处理器指令,替换为运行时的许可类型判断 - 第三步:所有和许可相关的分支代码都保留编译到程序集,运行时根据许可状态动态执行
示例代码:
using System.IO; // 许可类型枚举 public enum LicenseType { Trial, Licensed, Invalid } // 许可证工具类,负责读取解析DAT格式许可 public static class LicenseHelper { // 替换为实际的DAT许可证文件路径 private const string LicenseFilePath = "license.dat"; public static LicenseType GetCurrentLicenseType() { if (!File.Exists(LicenseFilePath)) return LicenseType.Trial; try { // 这里替换为实际的DAT文件读取、解密、校验逻辑 var content = File.ReadAllText(LicenseFilePath).Trim(); // 示例判断:DAT文件包含有效授权标记则返回正式许可,否则返回试用 return content.Contains("VALID_LICENSE_SIGN") ? LicenseType.Licensed : LicenseType.Trial; } catch { return LicenseType.Trial; } } // 监听许可文件变更的方法,用于热切换场景 public static void WatchLicenseChange(Action onChange) { var watcher = new FileSystemWatcher(Path.GetDirectoryName(LicenseFilePath), Path.GetFileName(LicenseFilePath)) { NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.Size }; watcher.Changed += (s, e) => onChange(); watcher.Created += (s, e) => onChange(); watcher.Deleted += (s, e) => onChange(); watcher.EnableRaisingEvents = true; } } public static class SomeStaticClass { public static string PropertyId { get; set; } } class Program { static void Main(string[] args) { // 初始化前先读取当前许可类型 var currentLicense = LicenseHelper.GetCurrentLicenseType(); // 替换原来的预处理器分支 if (currentLicense == LicenseType.Trial) { SomeStaticClass.PropertyId = "10023"; // 试用版相关初始化代码 } else if (currentLicense == LicenseType.Licensed) { SomeStaticClass.PropertyId = "10024"; // 正式版相关初始化代码 } // 注册对应许可版本的事件 // 创建对应许可版本的会话 // 后续业务逻辑... // 监听许可文件变更,触发重载流程 LicenseHelper.WatchLicenseChange(() => { // 这里触发重载逻辑,推荐用进程重启方案,避免静态资源残留问题 RestartApplication(); }); } // 应用重启方法,重新走Main初始化流程 static void RestartApplication() { // 释放当前进程占用的所有资源、会话、引擎实例 // 这里替换为实际的资源释放逻辑,比如关闭数据库连接、销毁引擎实例等 var currentProcessPath = Environment.ProcessPath; if (currentProcessPath != null) { System.Diagnostics.Process.Start(currentProcessPath); Environment.Exit(0); } } }
2 许可升降级后的逻辑切换方案
- 进程自动重启方案(优先推荐):用户更新许可文件后,程序监听到变更自动重启,重新执行Main方法的初始化逻辑,完全重置所有会话、异常处理器、引擎配置,没有静态变量残留的风险,实现成本最低,稳定性最高。
- 运行时热重载方案:如果业务不允许重启进程,需要把所有许可相关的依赖都封装为非静态的服务实例,许可变更时先销毁旧的服务实例,再根据新的许可类型重新初始化所有实例、注册事件、创建会话,需要额外处理静态变量重置、内存泄漏、未完成请求的兼容问题。
- 下次启动生效方案:许可变更后给用户弹窗提示,下次启动程序时自动切换许可模式,不需要额外监听逻辑,实现最简单,缺点是切换不会立即生效。
3 许可变更后重载Main流程的注意事项
- 静态变量需要显式重置:所有和许可相关的静态属性(比如示例中的
SomeStaticClass.PropertyId)在重载前需要恢复默认值,避免旧值残留。 - 资源必须完全释放:原有会话、引擎、文件句柄、网络连接等资源要在重载前正确释放,避免出现资源占用冲突。
- 用户数据临时保存:如果采用重启方案,需要在重启前临时保存用户未完成的操作数据,重启后自动恢复,避免用户数据丢失。
内容的提问来源于stack exchange,提问作者Gani.one
相关产品推荐
相关产品推荐

