深入· 04
常见问题
九个在 issue 里反复出现的问题,以及它们各自对应的那一处设计。
重新打包之后,装出来是两个软件
Inno 靠 AppId 认应用。SealPack 默认由主程序的产品身份推导它,所以同一份 exe 重新打包会覆盖升级。
两个版本并存通常意味着下面某一件事发生了:
- 换了工程(哪怕选的是同一份 exe)—— 如果用的是 v0.1.0,那时 AppId 还取自工程 ID;
- 主程序的
ProductName或CompanyName改了 —— 那本来就该当成另一个应用; - 「需要管理员权限」这个开关在两次构建之间变过 —— 它决定卸载键写在 HKCU 还是 HKLM。
想接回旧的 AppId,在打包选项的「应用标识」里手工填入旧值即可。完整说明见 应用标识与覆盖安装。
打包报 Unrecognized [Setup] section directive "EncryptionKeyDerivation"
生成的脚本里出现了 ISCC 不认识的指令,最常见的原因是用到了旧版 Inno Setup。
EncryptionKeyDerivation 是 6.5 才有的。
工具解析顺序是「用户设置 > 内置 > 下载目录」,所以内置目录里的一份旧版本会静默压住下载到的 正确版本。去设置里看一眼实际用的是哪一个,或者把内置目录里那份旧的删掉。 历史上真的发生过:内置 6.1 而声明 6.7.3,症状就是这一句。
打包报 Couldn't open include file ... ChineseSimplified.isl
只有在你手工改过模板、把语言行写成了 compiler:Languages\ChineseSimplified.isl 时才会出现。
Inno 官方发行版不含简体中文,所以 compiler: 前缀在任何标准安装上都会失败。SealPack 自带的
翻译会复制到临时脚本旁边、用相对路径引用 —— 恢复默认模板即可回到这条路径上。
我改了模板,为什么开关不起作用了
因为模板被标记为「手工改过」(generated: false)。这时模板是唯一事实源,改开关不会覆盖它。
想交回开关托管,点提示条上的「用当前选项覆盖模板」;或者「恢复默认模板」。
两种操作都会把 generated 置回 true。
预览里看到的模板和真机不一样
预览侧的生成器是 Rust 的镜像实现,两边可能漂移。跑一次一致性校验:
pnpm run check:render-parity
它会用 Rust dump 出来的 fixture 与 TS 侧输出逐字比对。改过任何一侧的生成器之后都必须跑。
开了重命名之后,程序启动就崩
重命名会改掉类名与方法名。按名字反射查找、或者通过序列化跨程序集通信的程序会被破坏。
排查顺序:
- 把
renameMode改成letters(兼容性最好); - 关掉
renEnum(枚举成员名常被当作字符串序列化); - 关掉
renPublic(供外部调用的类库不要开这个); - 仍然崩就先用「基础」预设二分,确认是重命名还是别的保护。
日志里出现了口令原文
不应该发生。pipeline.rs::mask_secret 在日志的唯一出口按 SECRET_KEYS 遮掉
PASSWORD= / SNKEYPASS= / RENAMEPASSWORD= / KEYPASS=(大小写不敏感)。
如果确实看到了,说明某个工具的参数名不在表里。这是代码问题,不是配置问题 —— 新增敏感参数时必须同步那张表,它由单测逐键断言。
为什么只有 Windows 版
因为三个外部工具里有两个是 .NET Framework 程序,而整个「桌面化」部分(无边框窗口、8 个缩放热区、 Mica Alt 材质、自绘 caption 按钮、拦掉浏览器行为)都是照着 Windows 的交互习惯做的。 换平台不是重新编译一次的事,是把这些决定重新做一遍。
加密之后启动变慢,能接受吗
能接受,但要挑对开关。按对启动时间的影响从大到小:
antiTamper+tamperMode=jit—— 每次方法编译前校验,最明显;controlFlow(尤其cfIntensity调小)与cfJunk—— 体积与执行时间都涨;resources加密 —— 启动时解码资源;constants加密 —— 影响很小;antiIldasm、invalidMetadata—— 对运行时几乎零成本。
先用「标准」预设跑一遍,量一个基线,再逐项加。别一上来就「严格」—— 它包含的反篡改与防转储对兼容性的要求比性能更高。