!include "LogicLib.nsh" !include "getProcessInfo.nsh" !define /ifndef INSTALL_REGISTRY_KEY "Software\${APP_GUID}" !define /ifndef UNINSTALL_REGISTRY_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${UNINSTALL_APP_KEY}" Var pid !ifndef BUILD_UNINSTALLER Var ccHahaRecoveryDone Function CcHahaUninstallerParent Exch $R0 Push $R1 Push $R2 Push $R3 StrCpy $R2 0 cc_haha_uninstall_parent_find_first_quote: StrCpy $R1 $R0 1 $R2 StrCmp $R1 "" cc_haha_uninstall_parent_invalid StrCmp $R1 '"' cc_haha_uninstall_parent_after_first_quote IntOp $R2 $R2 + 1 Goto cc_haha_uninstall_parent_find_first_quote cc_haha_uninstall_parent_after_first_quote: IntOp $R2 $R2 + 1 StrCpy $R0 $R0 "" $R2 StrCpy $R2 0 cc_haha_uninstall_parent_find_second_quote: StrCpy $R1 $R0 1 $R2 StrCmp $R1 "" cc_haha_uninstall_parent_invalid StrCmp $R1 '"' cc_haha_uninstall_parent_have_file IntOp $R2 $R2 + 1 Goto cc_haha_uninstall_parent_find_second_quote cc_haha_uninstall_parent_have_file: StrCpy $R0 $R0 $R2 StrLen $R2 $R0 cc_haha_uninstall_parent_find_slash: IntOp $R2 $R2 - 1 IntCmp $R2 0 cc_haha_uninstall_parent_invalid 0 0 StrCpy $R1 $R0 1 $R2 StrCmp $R1 "\" cc_haha_uninstall_parent_done Goto cc_haha_uninstall_parent_find_slash cc_haha_uninstall_parent_invalid: StrCpy $R0 "" Goto cc_haha_uninstall_parent_done cc_haha_uninstall_parent_done: StrCpy $R0 $R0 $R2 Pop $R3 Pop $R2 Pop $R1 Exch $R0 FunctionEnd Function CcHahaFinalInstallDir Exch $R0 Push $R1 Push $R2 Push $R3 Push $R4 Push $R5 StrCpy $R1 "${APP_FILENAME}" StrLen $R2 $R1 StrLen $R3 $R0 StrCpy $R4 0 cc_haha_final_install_find_name: IntCmp $R4 $R3 cc_haha_final_install_append 0 cc_haha_final_install_append StrCpy $R5 $R0 $R2 $R4 StrCmp $R5 $R1 cc_haha_final_install_done IntOp $R4 $R4 + 1 Goto cc_haha_final_install_find_name cc_haha_final_install_append: StrCpy $R0 "$R0\${APP_FILENAME}" cc_haha_final_install_done: Pop $R5 Pop $R4 Pop $R3 Pop $R2 Pop $R1 Exch $R0 FunctionEnd Function CcHahaRecoverLegacy InitPluginsDir File /oname=$PLUGINSDIR\recover-legacy-install-data.ps1 "${BUILD_RESOURCES_DIR}\recover-legacy-install-data.ps1" ReadRegStr $4 HKCU "${INSTALL_REGISTRY_KEY}" InstallLocation ReadRegStr $5 HKLM "${INSTALL_REGISTRY_KEY}" InstallLocation ReadRegStr $R0 HKCU "${UNINSTALL_REGISTRY_KEY}" UninstallString ${If} $R0 == "" !ifdef UNINSTALL_REGISTRY_KEY_2 ReadRegStr $R0 HKCU "${UNINSTALL_REGISTRY_KEY_2}" UninstallString !endif ${EndIf} ${If} $4 == "" ${AndIf} $R0 != "" Push $R0 Call CcHahaUninstallerParent Pop $4 ${EndIf} ReadRegStr $R1 HKLM "${UNINSTALL_REGISTRY_KEY}" UninstallString ${If} $R1 == "" !ifdef UNINSTALL_REGISTRY_KEY_2 ReadRegStr $R1 HKLM "${UNINSTALL_REGISTRY_KEY_2}" UninstallString !endif ${EndIf} ${If} $5 == "" ${AndIf} $R1 != "" Push $R1 Call CcHahaUninstallerParent Pop $5 ${EndIf} ReadEnvStr $2 APPDATA ReadEnvStr $3 USERPROFILE ReadEnvStr $6 CLAUDE_CONFIG_DIR ReadEnvStr $7 CC_HAHA_APP_PORTABLE_DIR ${If} $2 == "" StrCpy $0 "21" StrCpy $1 "missing current-user APPDATA" Return ${EndIf} ${If} $3 == "" StrCpy $0 "21" StrCpy $1 "missing current-user USERPROFILE" Return ${EndIf} Push "$INSTDIR" Call CcHahaFinalInstallDir Pop $9 DetailPrint "Checking registered installations for legacy Claude Code Haha data..." nsExec::ExecToStack '"$SYSDIR\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "$PLUGINSDIR\recover-legacy-install-data.ps1" -PerUserInstallDir "$4" -PerMachineInstallDir "$5" -CandidateInstallDir "$9" -UserDataDir "$2\Claude Code Haha" -RecoveryRoot "$3\Claude Code Haha Data\Recovered" -ProcessName "${PRODUCT_FILENAME}.exe" -ActiveConfigDir "$6" -ActiveConfigManaged "$7" -InstallerIdentitySafety "$8"' Pop $0 Pop $1 FunctionEnd !macro CcHahaRunLegacyRecovery ${If} $ccHahaRecoveryDone != "1" StrCpy $8 "trusted-user" ${If} ${UAC_IsAdmin} ${AndIfNot} ${UAC_IsInnerInstance} StrCpy $8 "untrusted-elevated" ${EndIf} ${If} ${UAC_IsInnerInstance} StrCpy $8 "trusted-uac-outer" !insertmacro UAC_AsUser_Call Function CcHahaRecoverLegacy ${UAC_SYNCREGISTERS}|${UAC_SYNCOUTDIR}|${UAC_SYNCINSTDIR} ${Else} Call CcHahaRecoverLegacy ${EndIf} ${If} $0 != "0" DetailPrint "Legacy data recovery stopped the installer (helper exit code: $0; output: $1)" MessageBox MB_ICONSTOP|MB_OK "Claude Code Haha cannot safely recover data stored inside the old application directory. Close the running app and run this installer normally, not as Administrator. The old version and its data have not been removed.$\r$\n$\r$\n无法安全恢复旧安装目录中的数据。请关闭旧程序,并以普通方式(不要使用“以管理员身份运行”)重新运行安装程序。旧版本和原数据尚未删除。" SetErrorLevel 20 Quit ${EndIf} StrCpy $ccHahaRecoveryDone "1" DetailPrint "Legacy Claude Code Haha data safety check completed" ${EndIf} !macroend !endif !macro customCheckAppRunning !insertmacro IS_POWERSHELL_AVAILABLE !insertmacro _CHECK_APP_RUNNING !ifndef BUILD_UNINSTALLER !insertmacro CcHahaRunLegacyRecovery !endif !macroend !ifndef BUILD_UNINSTALLER !macro customPageAfterChangeDir Function CcHahaRecoveryBeforeInstall ${If} ${UAC_IsInnerInstance} !insertmacro CcHahaRunLegacyRecovery ${EndIf} Abort FunctionEnd Page custom CcHahaRecoveryBeforeInstall !macroend !macro customInit StrCpy $ccHahaRecoveryDone "0" ${If} ${UAC_IsInnerInstance} ${AndIf} ${Silent} !insertmacro CcHahaRunLegacyRecovery ${EndIf} !macroend !endif