fix(windows): NSIS 安装包注册 OpenLess TSF DLL — 修"输入法后端:不可用"
## 现象
1.2.15 起在 Settings 页"Windows 输入法后端"出现 Pill「不可用」。`get_windows_ime_status()`
查 HKLM 注册表四件套(COM CLSID + TSF LanguageProfile + 三个 Category),缺一即报 NotInstalled。
## 根因
- MSI 通过 wix/openless-ime.wxs 的 RegisterOpenLessIme* CustomAction 跑 regsvr32 → 注册齐全。
- NSIS 包既没把 OpenLessIme.dll 打进去(wxs.componentRefs 是 MSI-only),也没 hook 跑
regsvr32 → 用 setup.exe 安装的用户、走 updater 自动升级的存量用户全部命中"不可用"。
- 由于 updater latest-windows-x86_64.json 是 NSIS pass 写的,老 MSI 用户每次更新后也
会被替换为没 TSF 的 NSIS 版本。
## 修复
- 加 src-tauri/installer.nsh:NSIS_HOOK_POSTINSTALL/PREUNINSTALL 跑 regsvr32 注册/反注册。
- bundle.resources map 把 OpenLessIme.dll 拷贝到 $INSTDIR\tsf-ime\OpenLessIme.dll
(target 路径避开 wxs File 已声明的 windows-ime\x64\,避免 MSI component 路径冲突)。
- bundle.windows.nsis.installMode = "perMachine",让 NSIS 以管理员身份运行(写 HKLM 必需)。
- CI 在 build native dll 后把真 dll 复制到 src-tauri/openless-ime-payload/x64/OpenLessIme.dll;
仓库 commit 0 字节占位文件,让本地 mac 端 tauri build 也能 resolve resources 路径。
- build-mac.sh 与 Linux build 步骤加 --config '{"bundle":{"resources":{}}}' 跳过 Windows-only
的 dll 占位,避免污染 mac .app / Linux .deb/.rpm/.AppImage。
## Trade-off
- NSIS perMachine 升级需要 UAC,老 currentUser 用户首次升级时多一次 UAC 提示。
- MSI 包里 dll 会有两份(wxs File + bundle.resources),磁盘冗余 ~几百 KB,无功能影响。
This commit is contained in:
1 parent
463a6d9716
commit
5aec74653b
5 files changed
+52
-3
No files matched your search
@@ -214,6 +214,14 @@ jobs:
|
||||
Write-Host "[ok] built $dll (exported $($t.EnvName))"
|
||||
}
|
||||
|
||||
# bundle.resources 引用的是 src-tauri/openless-ime-payload/x64/OpenLessIme.dll
|
||||
# (仓库里 commit 的是 0 字节占位让 mac 本地 build 也能 resolve)。
|
||||
# Windows CI 这里用真 x64 dll 覆盖占位,让 NSIS / MSI 包装的是真 dll。
|
||||
$payloadDir = Join-Path $appRoot 'src-tauri\openless-ime-payload\x64'
|
||||
New-Item -ItemType Directory -Force -Path $payloadDir | Out-Null
|
||||
Copy-Item -Force -Path $env:OPENLESS_IME_DLL_X64 -Destination (Join-Path $payloadDir 'OpenLessIme.dll')
|
||||
Write-Host "[ok] copied real x64 dll into bundle.resources payload path"
|
||||
|
||||
# ── Windows tauri build:保持 bash shell,因为 PowerShell 调外部命令
|
||||
# 会把 '{"bundle":...}' 的内部双引号吃掉、让 tauri 收到无效 JSON。
|
||||
# 用 set +e + GITHUB_ENV 把 exit code 传到下一步给 Repair 判断。
|
||||
@@ -299,6 +307,7 @@ jobs:
|
||||
Write-Host "[ok] MSI rebuilt at $msiPath"
|
||||
|
||||
# ── Linux:产 deb / rpm / AppImage ──
|
||||
# bundle.resources 里的 Windows TSF DLL 占位对 Linux 包没意义,用空 map 覆盖跳过。
|
||||
- name: Build (Linux)
|
||||
if: matrix.platform == 'ubuntu-22.04'
|
||||
shell: bash
|
||||
@@ -308,9 +317,11 @@ jobs:
|
||||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
|
||||
run: |
|
||||
if [ -n "${TAURI_SIGNING_PRIVATE_KEY:-}" ]; then
|
||||
npm run tauri -- build --bundles deb,rpm,appimage --config '{"bundle":{"createUpdaterArtifacts":true}}'
|
||||
npm run tauri -- build --bundles deb,rpm,appimage \
|
||||
--config '{"bundle":{"resources":{},"createUpdaterArtifacts":true}}'
|
||||
else
|
||||
npm run tauri -- build --bundles deb,rpm,appimage
|
||||
npm run tauri -- build --bundles deb,rpm,appimage \
|
||||
--config '{"bundle":{"resources":{}}}'
|
||||
fi
|
||||
|
||||
- name: Disambiguate macOS updater bundle filename
|
||||
|
||||
@@ -25,7 +25,9 @@ else
|
||||
fi
|
||||
|
||||
echo "▶ tauri build"
|
||||
TAURI_BUILD_ARGS=(build)
|
||||
# bundle.resources 里有 Windows TSF DLL(仅 NSIS/MSI 需要),mac 端用空 map 覆盖避免
|
||||
# 把 0 字节占位 OpenLessIme.dll 打进 .app/Contents/Resources。
|
||||
TAURI_BUILD_ARGS=(build --config '{"bundle":{"resources":{}}}')
|
||||
if [ -n "${TAURI_SIGNING_PRIVATE_KEY:-}" ] || [ -n "${TAURI_SIGNING_PRIVATE_KEY_PATH:-}" ]; then
|
||||
TAURI_BUILD_ARGS+=(--config '{"bundle":{"createUpdaterArtifacts":true}}')
|
||||
fi
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
; NSIS installer hook:注册 / 反注册 OpenLess TSF 输入法 DLL。
|
||||
;
|
||||
; 背景:MSI 包通过 wix/openless-ime.wxs 的 CustomAction 跑 regsvr32,可正常注册到
|
||||
; HKLM 下的 TSF 注册表四件套;NSIS 包没有等价钩子 → NSIS 安装的用户在
|
||||
; "设置 → 权限"页面看到 "Windows 输入法后端:不可用"。
|
||||
;
|
||||
; 这里的 hook 在 NSIS 安装/卸载流程里调 regsvr32 把 OpenLessIme.dll 注册到 HKLM。
|
||||
; bundle.resources 把 DLL 拷到 $INSTDIR\tsf-ime\OpenLessIme.dll
|
||||
; (resources map 的 target 必须避开 wxs fragment 已声明的 windows-ime\x64\
|
||||
; 路径,否则 MSI 包里同一路径会被两个 component 占用)。
|
||||
; tauri.conf.json 的 nsis.installMode = "perMachine" 让 NSIS 以管理员身份运行
|
||||
; (写 HKLM 必需)。
|
||||
;
|
||||
; regsvr32 失败时不阻塞安装:用户仍可以靠 SendInput / 粘贴兜底完成上屏。
|
||||
|
||||
!macro NSIS_HOOK_POSTINSTALL
|
||||
DetailPrint "Registering OpenLess TSF IME ..."
|
||||
nsExec::ExecToLog '"$SYSDIR\regsvr32.exe" /s "$INSTDIR\tsf-ime\OpenLessIme.dll"'
|
||||
Pop $0
|
||||
${If} $0 != 0
|
||||
DetailPrint "OpenLess TSF IME registration failed (exit $0); fallback insertion paths still work."
|
||||
${EndIf}
|
||||
!macroend
|
||||
|
||||
!macro NSIS_HOOK_PREUNINSTALL
|
||||
DetailPrint "Unregistering OpenLess TSF IME ..."
|
||||
nsExec::ExecToLog '"$SYSDIR\regsvr32.exe" /s /u "$INSTDIR\tsf-ime\OpenLessIme.dll"'
|
||||
Pop $0
|
||||
!macroend
|
||||
Whitespace-only changes.
@@ -79,6 +79,9 @@
|
||||
"icons/icon.icns",
|
||||
"icons/icon.ico"
|
||||
],
|
||||
"resources": {
|
||||
"openless-ime-payload/x64/OpenLessIme.dll": "tsf-ime/OpenLessIme.dll"
|
||||
},
|
||||
"macOS": {
|
||||
"minimumSystemVersion": "12.0",
|
||||
"infoPlist": "Info.plist",
|
||||
@@ -93,6 +96,10 @@
|
||||
"OpenLessImeDllX64Component",
|
||||
"OpenLessImeDllX86Component"
|
||||
]
|
||||
},
|
||||
"nsis": {
|
||||
"installMode": "perMachine",
|
||||
"installerHooks": "installer.nsh"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user