installer: let the packaging carry a prerelease version string
Two independent obstacles surfaced the first time a version with a hyphen reached the installer: - Inno Setup's VersionInfoVersion only accepts digits and dots, so ISCC aborted on 0.7.1-dev.20261019.<hash>. AppVersion, the output filename and the versioned DLL directory are free text and keep the full string; only VersionInfoVersion moves to a separate MyVersionInfo define that Prepare-PackageFiles.ps1 fills with the part before the hyphen, failing loudly if what remains is not numeric. Releases pass a bare semver, strip nothing, and behave exactly as before. - TsfRoot64 called ApplyPathRedirRulesForCurrentProcess, an Inno Setup 7 support function the windows-2025 runner's 6.7.1 does not have. #925 added it five hours after the last hosted-compiler run, and every release since then compiled on the self-hosted Inno 7, so the latent break never fired; the dev-build's hosted package job is the first to execute that path. The call was a no-op anyway: with ArchitecturesInstallIn64BitMode=x64compatible the setup process is 64-bit on every supported OS, so {sys} already expands to the real System32 and no WOW64 redirection applies. Expand the constant directly, with the #434 warning in this README updated to name the function explicitly.
This commit is contained in:
3 files changed
+35
-6
No files matched your search
@@ -347,6 +347,17 @@ $updatedIss = [regex]::Replace(
|
||||
'(?m)^#define\s+MyAppVersion\s+"[^"]+"\s*$',
|
||||
"#define MyAppVersion `"$TargetVersion`""
|
||||
)
|
||||
# VersionInfoVersion 只接受数字和点号;从目标版本剥掉 -后缀(dev 构建的
|
||||
# 0.7.1-dev.20261019.<hash> → 0.7.1),正式版本剥了也原样。
|
||||
$versionInfo = ($TargetVersion -replace '-.*$', '')
|
||||
if ($versionInfo -notmatch '^[0-9]+(\.[0-9]+)*$') {
|
||||
throw "目标版本剥掉后缀后不是数字版本号,无法写进 VersionInfoVersion:$TargetVersion"
|
||||
}
|
||||
$updatedIss = [regex]::Replace(
|
||||
$updatedIss,
|
||||
'(?m)^#define\s+MyVersionInfo\s+"[^"]+"\s*$',
|
||||
"#define MyVersionInfo `"$versionInfo`""
|
||||
)
|
||||
# .gitattributes pins this repo to eol=lf; emit LF so packaging does not leave the file as a
|
||||
# CRLF-only diff that git flags as modified while `git diff` shows no textual change.
|
||||
$updatedIss = $updatedIss.TrimEnd("`r", "`n") + "`n"
|
||||
|
||||
+12
-2
@@ -1,8 +1,9 @@
|
||||
# Metasequoia IME Installer
|
||||
|
||||
本目录的脚本从 Windows 合仓目录收集产物、签名、用 Inno Setup 打成安装包。它服务两条流程:
|
||||
本目录的脚本从 Windows 合仓目录收集产物、签名、用 Inno Setup 打成安装包。它服务三条流程:
|
||||
|
||||
- **正式发布**:由 `MSIME-Windows` 的 release workflow 驱动,用真实证书签名包内全部 EXE/DLL 和最终安装包;产物是挂在 Release 上的 `MetasequoiaIME_Setup_v<版本>.exe`,并携带与 Release 二进制匹配的 PDB 符号文件。见下面「CI 契约」
|
||||
- **开发构建**:由 `dev-build.yml` workflow 驱动,runner 上现场生成自签名证书并签名,产物随 artifact 分发。见下面「Dev build」
|
||||
- **本地测试**:手工跑,用本机自签名证书,用来在自己机器上验证安装流程。本文其余部分讲的是这条
|
||||
|
||||
版本号不是固定的,由 `Prepare-PackageFiles.ps1` 的 `-TargetVersion` 决定,默认 `0.0.1`;正式发布时 CI 传入真实版本。
|
||||
@@ -11,6 +12,15 @@
|
||||
|
||||
签名脚本会在你自己的机器上生成并复用一张自签名测试证书。
|
||||
|
||||
## Dev build
|
||||
|
||||
`dev-build.yml` workflow 给没有本地工具链的贡献者出可安装的包。触发见 [CONTRIBUTING.md](../CONTRIBUTING.md#没有本地工具链时dev-build-workflow)。签名证书由 `sign-dev-build.ps1` 在 runner 上现场生成,subject 固定为 `CN=Metasequoia IME Dev Build Code Signing`,私钥只在 runner 内存里存在一次构建;公钥 `.cer` 随 artifact 分发,用户用 `import-dev-trust.ps1` 导入本机受信任存储(按 subject 清旧导新,重复构建不会膨胀存储)。
|
||||
|
||||
- `sign-dev-build.ps1` 复用同一次运行早先创建的证书,所以包内二进制和安装包总在同一签名下;`DEV_CERT_PATH` 指出 `.cer` 的导出位置
|
||||
- `import-dev-trust.ps1` 也随 artifact 分发,用户解压后在管理员 PowerShell 里直接跑
|
||||
- 版本号带 `-dev.<日期>.<commit>`,由 `scripts/dev-build-version.py` 从 `version.txt` 派生;设置页的更新检查会剥掉 `-dev` 后缀做数字比较,dev 包不会提示升级
|
||||
- 不要把这两个脚本接进 release 路径:正式发布的签名在 `scripts/ci/sign-binaries.ps1` 或 SignPath,两套互不相干
|
||||
|
||||
## CI 契约
|
||||
|
||||
根 `.github/workflows/release.yml` **不加修改地调用本目录的 `Prepare-PackageFiles.ps1` 和 `Compile-Installer.ps1`**。源目录名是 `Prepare-PackageFiles.ps1` 的参数,不是写死在脚本里的字面量:默认值为 `windows/`、`server/` 和仓根授权文件;旧目录或自定义布局通过参数覆盖。回归检查同时执行默认路径和显式参数的打包。辅助码默认读取 `engine/helpcode/`,词库缓存位于 `MetasequoiaImeDict/out/`。
|
||||
@@ -71,7 +81,7 @@ Windows CI 运行 `installer/tests/cloud-choice.ps1`,用 Inno Setup 跑八个
|
||||
安装包不携带 VC 运行库,它是系统级共享组件。缺了它 Server 起不来,而这个故障出现在安装结束之后,用户看不到任何解释。所以 `msime_setup.iss` 的 `InitializeSetup` 在安装开始前先查一遍,缺了就当场说清楚,并给出下载地址。界面全部由 `msimeui` 以 Direct2D 绘制,不再依赖 WebView2 Runtime;旧版本留下的 WebView2 用户数据(`ProgramData\metasequoiaime\webview2`、`webview2-settings`,以及 `%LOCALAPPDATA%\metasequoiaime` 下的同名回退目录)由安装器在升级和卸载时清掉。
|
||||
|
||||
- **Visual C++ 2015–2022 可再发行组件包(x64)**:读 `Software\Microsoft\VisualStudio\14.0\VC\Runtimes\x64` 的 `Installed` / `Major` / `Minor`,`HKLM32` 和 `HKLM64` 两个视图都查。要求 **14.40 以上**(常量 `VCRuntimeMinMinor`):`server_exe\` 里的 exe 用 MSVC 14.40+(VS 2022 17.10 起)编译并导入 `msvcp140.dll`,这一版起 `std::mutex` 的构造函数是 constexpr,配上更旧的 `msvcp140.dll` 会在第一次加锁时访问冲突、无声闪退——设置页「点了没反应」就是这个现象。装了 2019 / 早期 2022 运行库的机器同样有 `Installed=1`,所以必须比版本号。构建工具链升级到要求更高 redist 时同步调高这个常量。32 位 TSF DLL 用静态 CRT(`windows/CMakeLists.txt` 的 `CMAKE_MSVC_RUNTIME_LIBRARY`),所以不检查 x86 redist
|
||||
- **不要改成查 `System32` 里的 DLL。** Setup.exe 是 32 位进程,Pascal Script 的 `FileExists` 会被 WOW64 重定向到 `SysWOW64`,查到的是 x86 运行库;只装了 x64 redist 的机器会被误判成缺少 x64 运行库。绕开重定向的办法不可移植:`EnableFsRedirection` 在 Inno Setup 7 里已被移除,而它的替代品在 CI 用的 6.x 里还不存在
|
||||
- **不要改成查 `System32` 里的 DLL,也不要在 Pascal Script 里用 `ApplyPathRedirRulesForCurrentProcess`。** 那是 Inno Setup 7 的 support function,CI 的 6.7.1 没有它,ISCC 会报 `Unknown identifier`(#925 引入后第一次在 hosted runner 上编安装包就炸了,#55e1127a 改回直接展开 `{sys}`)。Setup 在 x64/ARM64 上是 64 位进程,`{sys}` 本来就不经重定向;需要 32 位视图时用 `{syswow64}`
|
||||
- 缺组件或版本过旧时弹一次对话框,区分「没装」和「已装 x.y 但过旧」,列出直接下载链接(`https://aka.ms/vc14/vc_redist.x64.exe`)和说明页:选「是」直接下载安装包并结束安装,选「否」继续装。**不阻断安装**——用户可能马上就要去补组件,也可能只是在准备环境。静默安装(CI、批量部署)用 `SuppressibleMsgBox` 默认「否」直接继续,缺什么已经写进安装日志(`/LOG=`)
|
||||
|
||||
## 依赖
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
|
||||
#define MyAppName "Metasequoia IME 水杉输入法"
|
||||
#define MyAppVersion "0.0.1"
|
||||
; VersionInfoVersion 是 PE 的 VERSIONINFO,只接受数字和点号;dev 构建的 MyAppVersion 带
|
||||
; -dev.<日期>.<hash> 后缀(Prepare-PackageFiles.ps1 会把数字部分同步写进这个 define),
|
||||
; 文件名与 AppVersion 用完整串,这里只用数字段。
|
||||
#define MyVersionInfo "0.0.1"
|
||||
#define MyAppPublisher "Metasequoia"
|
||||
#define MyAppExeName "MetasequoiaImeServer.exe"
|
||||
#define MySettingsExeName "MetasequoiaImeSettings.exe"
|
||||
@@ -36,7 +40,11 @@
|
||||
#define MySourceRoot "."
|
||||
; TSF DLL 装在系统目录下:CS2 等开启 Trusted Mode 的游戏只放行「位于系统目录且有代码签名」的
|
||||
; 第三方 in-proc DLL,装在 Program Files 的 DLL 连加载都会被拒,输入法在游戏里根本切不出来。
|
||||
; 本安装器是 32 位进程,[Code] 里访问 64 位那份要先过 ApplyPathRedirRulesForCurrentProcess。
|
||||
; 本安装器在 x64/ARM64 上以 64 位模式运行(ArchitecturesInstallIn64BitMode),
|
||||
; Pascal Script 里访问 {sys} 就是真正的 System32,没有 WOW64 重定向可绕。
|
||||
; 不要在这里用 ApplyPathRedirRulesForCurrentProcess:那是 Inno Setup 7 的 support
|
||||
; function,windows-2025 runner 的 6.7.1 没有它,ISCC 直接报 Unknown identifier
|
||||
; (#434 的告诫,见 installer/README.md)。
|
||||
#define MyTsfRoot64 "{sys}\IME\MetasequoiaIME"
|
||||
#define MyTsfRoot32 "{syswow64}\IME\MetasequoiaIME"
|
||||
#ifdef LightPackage
|
||||
@@ -69,7 +77,7 @@ ArchitecturesAllowed=x64compatible
|
||||
ArchitecturesInstallIn64BitMode=x64compatible
|
||||
UninstallDisplayName={#MyAppName}
|
||||
UninstallDisplayIcon={commonpf64}\metasequoiaime\MetasequoiaIME.ico
|
||||
VersionInfoVersion={#MyAppVersion}
|
||||
VersionInfoVersion={#MyVersionInfo}
|
||||
|
||||
[Languages]
|
||||
Name: "chinesesimplified"; MessagesFile: "compiler:Languages\ChineseSimplified.isl"
|
||||
@@ -718,10 +726,10 @@ begin
|
||||
'现有数据将从这里迁移:' + NewLine + Space + ResolvePreviousDataDir;
|
||||
end;
|
||||
|
||||
{ 本进程能直接访问的 TSF 根目录。32 位安装器里不经改写的 System32 会被 WOW64 落到 SysWOW64。}
|
||||
// 本进程能直接访问的 TSF 根目录。64 位模式下 sys 常量不经重定向,直接就是 System32。
|
||||
function TsfRoot64: String;
|
||||
begin
|
||||
Result := ApplyPathRedirRulesForCurrentProcess(True, ExpandConstant('{#MyTsfRoot64}'));
|
||||
Result := ExpandConstant('{#MyTsfRoot64}');
|
||||
end;
|
||||
|
||||
function TsfRoot32: String;
|
||||
|
||||
Reference in new issue
Block a user