Skip to content

fix: register Windows IME from NSIS installer#268

Merged
H-Chris233 merged 9 commits into
Open-Less:mainfrom
millionart:codex/register-windows-ime-nsis-installer
May 5, 2026
Merged

fix: register Windows IME from NSIS installer#268
H-Chris233 merged 9 commits into
Open-Less:mainfrom
millionart:codex/register-windows-ime-nsis-installer

Conversation

@millionart
Copy link
Copy Markdown
Contributor

@millionart millionart commented May 5, 2026

User description

Summary

  • Register the Windows TSF IME from the NSIS installer by copying the CI-built x64/x86 OpenLessIme.dll artifacts and invoking the matching regsvr32 during install/uninstall hooks.
  • Add an elevated installer smoke script that verifies the same COM, TSF language profile, and category registry keys used by the backend installed-state check.
  • Run the smoke in Windows release CI for both the NSIS .exe and repaired MSI artifacts after bundle creation.

Validation

  • node scripts/windows-package-msvc.test.mjs
  • PowerShell parser check for scripts/windows-ime-install-smoke.ps1
  • cargo check --manifest-path src-tauri\Cargo.toml
  • npm.cmd run build
  • scripts\windows-ime-build.ps1 -Configuration Release -Platform x64
  • scripts\windows-ime-build.ps1 -Configuration Release -Platform Win32
  • npm.cmd run tauri -- build --bundles nsis
  • Local elevated install smoke against OpenLess_1.2.19_x64-setup.exe passed and reported Windows IME backend would report installed, then uninstalled.

Note: local cargo test --manifest-path src-tauri\Cargo.toml did not reach tests on this machine because the test executable failed to start with STATUS_ENTRYPOINT_NOT_FOUND; this appears to be a local runtime/linkage startup issue separate from this installer change.


PR Type

Enhancement, Tests


Description

  • Add NSIS installer hooks for Windows TSF IME registration (x64/x86)

  • Create elevated PowerShell smoke test to verify IME installation

  • Integrate smoke test into Windows release CI for NSIS and MSI

  • Update test assertions to cover NSIS hooks, smoke script, and CI


Diagram Walkthrough

flowchart LR
  A["NSIS Installer with hooks"] -- "registers x64/x86 OpenLessIme.dll" --> B["TSF IME Registration"]
  C["windows-ime-install-smoke.ps1"] -- "validates COM/TSF registry keys" --> B
  D["release-tauri.yml (Windows CI)"] -- "runs smoke after build" --> C
Loading

File Walkthrough

Relevant files
Tests
windows-ime-install-smoke.ps1
New Windows IME installer smoke test script                           

openless-all/app/scripts/windows-ime-install-smoke.ps1

  • Implements elevated PowerShell script to install NSIS/MSI and validate
    IME registration
  • Defines expected COM, TSF language profile, and category registry keys
    aligned with backend
  • Asserts DLL paths, x64/x86 COM registration, presence of OpenLess
    executable, and all backend-required keys
  • Supports parameterized installer path/kind and optional skip-uninstall
    flag
+199/-0 
windows-package-msvc.test.mjs
Extend build test assertions for NSIS IME and smoke           

openless-all/app/scripts/windows-package-msvc.test.mjs

  • Adds paths for new NSIS hooks, smoke script, and CI workflow to the
    test suite
  • Asserts NSIS hooks contain proper macro-based IME registration,
    rollback, and unregistration logic
  • Asserts tauri.conf.json now includes NSIS perMachine install mode and
    installerHooks path
  • Asserts smoke script structure (parameter validation, argument
    quoting, registry checks) and CI workflow integration
+113/-68
Configuration changes
release-tauri.yml
CI step to run IME installer smoke on Windows                       

.github/workflows/release-tauri.yml

  • Adds a new CI step to verify TSF IME registration for built Windows
    installers
  • Locates the NSIS .exe and MSI .msi artifacts in the bundle output
    directories
  • Invokes the smoke script with appropriate InstallerKind and fails job
    on non-zero exit
+18/-0   
tauri.conf.json
Configure NSIS for machine-wide IME registration                 

openless-all/app/src-tauri/tauri.conf.json

  • Sets NSIS installMode to "perMachine" to satisfy machine-wide TSF IME
    requirement
  • Points installerHooks to the newly created nsis/openless-ime-hooks.nsh
+4/-0     
Enhancement
openless-ime-hooks.nsh
NSIS installer hooks for Windows TSF IME                                 

openless-all/app/src-tauri/nsis/openless-ime-hooks.nsh

  • Defines NSIS macros to copy x64/x86 OpenLessIme.dll into installation
    directory
  • Registers IME DLLs via regsvr32 with architecture-appropriate fallback
    paths (Sysnative/SysWOW64)
  • Aborts installation with detailed message if registration fails; rolls
    back prior registration
  • Uninstall macros unregister DLLs without blocking on failure and clean
    up IME files/directories
+85/-0   

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

PR Reviewer Guide 🔍

(Review updated until commit ec9f658)

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ No major issues detected

Copy link
Copy Markdown
Contributor Author

Addressed the two review items in e67755d:

  • NSIS uninstall now aborts if either x64 or x86 TSF IME regsvr32 /u fails, so uninstall does not remove the DLLs after a failed unregister.
  • windows-ime-install-smoke.ps1 now quotes process arguments into a single command line before Start-Process, covering installer paths with spaces.

Validation run:

  • node scripts/windows-package-msvc.test.mjs
  • PowerShell parser check for scripts/windows-ime-install-smoke.ps1
  • git diff --check for the touched files

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e67755d04e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

!macro OPENLESS_IME_UNREGISTER_X86
DetailPrint "Unregistering OpenLess x86 TSF IME"
ExecWait '"$WINDIR\SysWOW64\regsvr32.exe" /s /u "$INSTDIR\windows-ime\x86\OpenLessIme.dll"' $0
!insertmacro OPENLESS_IME_ABORT_IF_FAILED $0 "x86 unregistration"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Do not abort uninstall when IME unregistration fails

Calling OPENLESS_IME_ABORT_IF_FAILED in the uninstall hooks makes the entire NSIS uninstall fail whenever regsvr32 /u returns non-zero (for example if the DLL was already removed/corrupted or COM state is partially broken). In that state users cannot remove OpenLess at all, which is a regression from the MSI path (openless-ime.wxs) where uninstall unregistration is Return="ignore" specifically to avoid blocking removal on cleanup errors.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in the follow-up commits on codex/register-windows-ime-nsis-installer:

  • NSIS uninstall now logs x64/x86 regsvr32 /u exit codes instead of aborting, matching the MSI Return="ignore" cleanup behavior.
  • The packaging assertion now explicitly verifies registration still aborts during install, while unregistration does not abort during uninstall.

Validation run locally:

  • node scripts/windows-package-msvc.test.mjs
  • PowerShell parser check for scripts/windows-ime-install-smoke.ps1

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

Persistent review updated to latest commit e67755d

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

Persistent review updated to latest commit 68ee9df

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 68ee9dfae4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +310 to +311
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\windows-ime-install-smoke.ps1 -InstallerPath $nsis.FullName -InstallerKind nsis
powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\scripts\windows-ime-install-smoke.ps1 -InstallerPath $msi.FullName -InstallerKind msi
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Fail CI when either installer smoke run fails

In the Windows verify step, both smoke scripts are invoked sequentially but there is no per-command exit check. On pwsh, GitHub Actions reports the step status from the last $LASTEXITCODE, so a failing NSIS smoke run can be masked if the MSI smoke run succeeds afterward. That lets a broken NSIS installer pass release verification even though this step is intended to validate both artifacts.

Useful? React with 👍 / 👎.

Comment on lines +131 to +132
assert.match(nsisHook, /OPENLESS_IME_ABORT_IF_FAILED \$0 "x64 unregistration"/, "NSIS uninstall should fail if x64 TSF unregistration fails");
assert.match(nsisHook, /OPENLESS_IME_ABORT_IF_FAILED \$0 "x86 unregistration"/, "NSIS uninstall should fail if x86 TSF unregistration fails");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Align packaging test with uninstall hook behavior

These assertions require uninstall abort macros that are not present in src-tauri/nsis/openless-ime-hooks.nsh, so the packaging test now fails deterministically (node scripts/windows-package-msvc.test.mjs fails at this check). Keeping this stale expectation breaks the repo’s own validation script and can block or confuse release-script verification.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

Persistent review updated to latest commit 933e014

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

Persistent review updated to latest commit eca76de

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

Persistent review updated to latest commit eca76de

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

Persistent review updated to latest commit 4a7a1b6

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4a7a1b6b8c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +150 to +151
assert.match(ciWorkflow, /InstallerKind nsis[\s\S]*\$LASTEXITCODE -ne 0[\s\S]*NSIS installer smoke failed/, "CI should fail immediately when the NSIS smoke run fails");
assert.match(ciWorkflow, /InstallerKind msi[\s\S]*\$LASTEXITCODE -ne 0[\s\S]*MSI installer smoke failed/, "CI should fail when the MSI smoke run fails");
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Align CI smoke step with asserted exit-code guards

These assertions require the workflow to check $LASTEXITCODE after each windows-ime-install-smoke.ps1 invocation, but .github/workflows/release-tauri.yml currently runs both installer smokes without those guards. As a result, node scripts/windows-package-msvc.test.mjs fails deterministically at this point, so the repository’s own packaging validation cannot pass until the workflow and test expectations are brought back into sync.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Addressed the current CI smoke exit-code feedback in b303ea4:

  • Added explicit $LASTEXITCODE checks after both NSIS and MSI windows-ime-install-smoke.ps1 invocations.
  • The Windows verification step now fails immediately with separate NSIS/MSI messages if either smoke run fails.

Validation run locally:

  • node scripts/windows-package-msvc.test.mjs
  • PowerShell parser check for scripts/windows-ime-install-smoke.ps1
  • git diff --check

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

Persistent review updated to latest commit b303ea4

Copy link
Copy Markdown
Contributor Author

@millionart millionart left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed the persistent review guide items in ec9f658:

  • NSIS now rolls back the already-registered x64 IME if x86 registration fails before aborting install, avoiding partial machine registration.
  • windows-ime-install-smoke.ps1 now asserts every backend-required registry key in ExpectedBackendKeys instead of only tracing them.

Validation run locally:

  • node scripts/windows-package-msvc.test.mjs
  • PowerShell parser check for scripts/windows-ime-install-smoke.ps1
  • git diff --check / git diff --cached --check

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

Persistent review updated to latest commit ec9f658

@H-Chris233 H-Chris233 self-requested a review May 5, 2026 12:20
@H-Chris233 H-Chris233 merged commit 5c1a796 into Open-Less:main May 5, 2026
2 checks passed
@millionart millionart deleted the codex/register-windows-ime-nsis-installer branch May 5, 2026 12:47
@millionart millionart restored the codex/register-windows-ime-nsis-installer branch May 5, 2026 12:48
appergb added a commit that referenced this pull request May 6, 2026
chore(release-prep): 清理 #268/#279 双 NSIS 方案残留
H-Chris233 pushed a commit to H-Chris233/openless that referenced this pull request May 6, 2026
main 上 Open-Less#268 (millionart/codex/register-windows-ime-nsis-installer) 与 Open-Less#279
(本人) 都修了 NSIS 注册 TSF DLL,merge Open-Less#279 时未手动解决冲突,导致:

1. tauri.conf.json 出现两个 windows.nsis block(line 92-95 和 105-108),
   serde_json 用最后写入的覆盖前面,结果 Open-Less#268 的 nsis/openless-ime-hooks.nsh
   被丢弃,实际生效的是 Open-Less#279 的 installer.nsh。
2. Open-Less#279 的 bundle.resources 把 dll 多打一份到 $INSTDIR\tsf-ime\,与 Open-Less#268
   PREINSTALL File 直接装到 $INSTDIR\windows-ime\ 并存。
3. installer.nsh 与 openless-ime-payload/ 残留为死代码。

Open-Less#268 方案更稳:x64 注册带 Sysnative + DisableX64FSRedirection 双保险,有
POSTUNINSTALL 清理 hook,有测试覆盖(4a7a1b6b/test、933e014a/test),且
不污染 MSI(不用 bundle.resources,避免 dll 重复)。

清理:
- 删除 tauri.conf.json 重复 nsis block,保留 nsis/openless-ime-hooks.nsh
- 删除 bundle.resources(Open-Less#268 不需要)
- 删除死文件 installer.nsh
- 删除死目录 openless-ime-payload/

release-tauri.yml 里"复制 dll 到 openless-ime-payload"步骤、build-mac.sh
与 Linux build 的 --config '{"bundle":{"resources":{}}}' override 暂留 —
没有 bundle.resources 后这些是 noop,不会破坏 build;当前 token 没有
workflow scope,等下一次有需求再清。
appergb pushed a commit that referenced this pull request May 6, 2026
主要修复
─────────
- fix(windows): NSIS 安装包注册 OpenLess TSF DLL(含 32-bit COM 注册到
  Wow6432Node + Sysnative 绕过 32-bit installer 的 WOW64 重定向);
  改 perMachine 安装让 regsvr32 能写 HKLM。修「Windows 输入法后端:不可用」
  自 1.2.15 起的长期 bug。
- fix(local-asr): 切走/删模型/手动释放时引擎真正归还 1+ GB RAM;下载稳定性
  4 次指数退避 + Range 分块 + 取消正确传播;点击下载即崩(tokio::spawn →
  tauri::async_runtime)。
- fix(tauri): Rust crate tauri 锁 ~2.10,避开 npm 端 @tauri-apps/api
  尚未发布 2.11 导致的跨 minor 版本检查 fail。
- fix(capsule): AudioBars 用 cubic-bezier 缓动 + 0.18s transition,圆点→
  长条形变在 60Hz audio level 高频更新下平滑混合,不再阶梯式跳变。
- fix(recorder): liveness watchdog + 全局超时;watchdog 从首次回调开始计时
  避免慢启动误报(issue #238)。
- fix(windows): hotkey trigger leak、capsule 视觉异常、音量计稳定(多 PR)。
- fix(credentials): 凭据状态按 active provider 判断。

新功能
─────────
- feat(asr): 本地 Qwen3-ASR-Flash 全链路 — 模型注册表、HF/HF-Mirror 4 并发
  分块下载、Settings → 模型设置页、Coordinator 第三分支接入。
- feat(i18n): 日本語 / 한국어 完整翻译(217 string × 2 语种)+ 5 locale
  在语言名后加 Beta 标识。
- feat(translation): 输出语言扩展为日 / 韩,与翻译链路解耦。
- feat(recording): 录音时静音系统输出,多会话共享 mute guard。
- feat(i18n): 繁體中文 UI 完整 + 简繁脚本随 UI 切换同步。
- feat(settings): 合并设置内外两个「关于」(QQ 群 / 反馈 / 源码 / 隐私
  全部并入弹窗的关于)+ 一键导出错误日志(plugin-dialog 选保存位置,
  跨 macOS / Windows)。

工程
─────────
- chore(ci): release-tauri.yml + ci.yml checkout 拉 submodule,修 mac 端
  qwen-asr build 缺源文件。
- chore(release-prep): 清理 #268/#279 双 NSIS 方案残留。
- chore(deps): 引入 tauri-plugin-dialog ~2 给前端 save dialog 用。
@millionart millionart deleted the codex/register-windows-ime-nsis-installer branch May 7, 2026 05:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants