fix(windows): NSIS x64 dll 用 Sysnative 绕过 WOW64 重定向

NSIS installer 是 32-bit 进程,进程内的 $SYSDIR / $WINDIR\System32 都因
WOW64 文件系统重定向变成 $WINDIR\SysWOW64,跑的是 32-bit regsvr32 → x64 dll
被注册到 HKLM\Software\Wow6432Node\Classes\CLSID(KEY_WOW64_32KEY 视图)。
但 windows_ime_profile.rs 用 KEY_WOW64_64KEY 校验时只看 HKLM\Software\Classes
\CLSID,永远查不到 → 仍判 RegistrationBroken("OpenLess COM registration is
missing")。

修复:x64 改用 $WINDIR\Sysnative\regsvr32.exe — 这是 32-bit 进程访问真
64-bit System32 的专用 alias,写入会落在 KEY_WOW64_64KEY 视图。x86 保持
SysWOW64 不变(确实需要 32-bit regsvr32 写 Wow6432Node)。
This commit is contained in:
baiqing committed 2026-05-06 10:52:12 +08:00
1 parent c52658b08b
commit 81fa80da69
1 file changed
+11 -4
+11 -4
View File
@@ -14,14 +14,21 @@
; 必须同时注册 x64 + x86 两份 dll:windows_ime_profile.rs 的
; inspect_windows_ime_registration() 会用 KEY_WOW64_64KEY 和 KEY_WOW64_32KEY 两次
; 检查 HKLM CLSID InprocServer32,少了任何一边都会被判 RegistrationBroken。
; - x64 用 $SYSDIR\regsvr32.exe (System32 = 64-bit on x64 Windows)
; - x86 用 $WINDIR\SysWOW64\regsvr32.exe (32-bit regsvr32 → 写 KEY_WOW64_32KEY)
;
; ⚠️ NSIS installer 自身是 32-bit 进程,会触发 WOW64 文件系统重定向:
; - 32-bit 进程里的 $SYSDIR / $WINDIR\System32 都被重定向到 $WINDIR\SysWOW64,
; 运行的是 32-bit regsvr32 → 注册结果落在 HKLM\Software\Wow6432Node(即
; KEY_WOW64_32KEY 视图),Rust 端 KEY_WOW64_64KEY 查不到 → 仍判"不可用"。
; - 32-bit 进程访问真正的 64-bit System32 必须走 $WINDIR\Sysnative 这个 alias。
; 因此:
; - x64 dll → $WINDIR\Sysnative\regsvr32.exe → 写 KEY_WOW64_64KEY 视图
; - x86 dll → $WINDIR\SysWOW64\regsvr32.exe → 写 KEY_WOW64_32KEY 视图
;
; regsvr32 失败时不阻塞安装:用户仍可以靠 SendInput / 粘贴兜底完成上屏。
!macro NSIS_HOOK_POSTINSTALL
DetailPrint "Registering OpenLess TSF IME (x64) ..."
nsExec::ExecToLog '"$SYSDIR\regsvr32.exe" /s "$INSTDIR\tsf-ime\x64\OpenLessIme.dll"'
nsExec::ExecToLog '"$WINDIR\Sysnative\regsvr32.exe" /s "$INSTDIR\tsf-ime\x64\OpenLessIme.dll"'
Pop $0
${If} $0 != 0
DetailPrint "OpenLess TSF IME x64 registration failed (exit $0); fallback insertion paths still work."
@@ -40,6 +47,6 @@
nsExec::ExecToLog '"$WINDIR\SysWOW64\regsvr32.exe" /s /u "$INSTDIR\tsf-ime\x86\OpenLessIme.dll"'
Pop $0
DetailPrint "Unregistering OpenLess TSF IME (x64) ..."
nsExec::ExecToLog '"$SYSDIR\regsvr32.exe" /s /u "$INSTDIR\tsf-ime\x64\OpenLessIme.dll"'
nsExec::ExecToLog '"$WINDIR\Sysnative\regsvr32.exe" /s /u "$INSTDIR\tsf-ime\x64\OpenLessIme.dll"'
Pop $0
!macroend