From 38df6ea1c184307d294ee467c4b1c6a488b6e289 Mon Sep 17 00:00:00 2001 From: Amr Bashir Date: Wed, 29 May 2024 22:33:24 +0300 Subject: [PATCH] fix(nsis): fix regression in shortcuts pointing to a non-existing file (#9909) --- .changes/nsis-shortcuts-regression.md | 6 + .../bundle/windows/templates/installer.nsi | 121 +++++++++++------- 2 files changed, 83 insertions(+), 44 deletions(-) create mode 100644 .changes/nsis-shortcuts-regression.md diff --git a/.changes/nsis-shortcuts-regression.md b/.changes/nsis-shortcuts-regression.md new file mode 100644 index 000000000..b3c55eece --- /dev/null +++ b/.changes/nsis-shortcuts-regression.md @@ -0,0 +1,6 @@ +--- +"tauri-bundler": "patch:bug" +--- + +Fix regression in NSIS where it created shortcuts that point to non-existent files. + diff --git a/tooling/bundler/src/bundle/windows/templates/installer.nsi b/tooling/bundler/src/bundle/windows/templates/installer.nsi index 70e90354a..f2f14d1b3 100644 --- a/tooling/bundler/src/bundle/windows/templates/installer.nsi +++ b/tooling/bundler/src/bundle/windows/templates/installer.nsi @@ -51,6 +51,10 @@ ${StrLoc} !define UNINSTALLERSIGNCOMMAND "{{uninstaller_sign_cmd}}" !define ESTIMATEDSIZE "{{estimated_size}}" +Var PassiveMode +Var UpdateMode +Var NoShortcutMode + Name "${PRODUCTNAME}" BrandingText "${COPYRIGHT}" OutFile "${OUTFILE}" @@ -194,21 +198,21 @@ Function PageReinstall nsis_tauri_utils::SemverCompare "${VERSION}" $R0 Pop $R0 ; Reinstalling the same version - ${If} $R0 == 0 + ${If} $R0 = 0 StrCpy $R1 "$(alreadyInstalledLong)" StrCpy $R2 "$(addOrReinstall)" StrCpy $R3 "$(uninstallApp)" !insertmacro MUI_HEADER_TEXT "$(alreadyInstalled)" "$(chooseMaintenanceOption)" StrCpy $R5 "2" ; Upgrading - ${ElseIf} $R0 == 1 + ${ElseIf} $R0 = 1 StrCpy $R1 "$(olderOrUnknownVersionInstalled)" StrCpy $R2 "$(uninstallBeforeInstalling)" StrCpy $R3 "$(dontUninstall)" !insertmacro MUI_HEADER_TEXT "$(alreadyInstalled)" "$(choowHowToInstall)" StrCpy $R5 "1" ; Downgrading - ${ElseIf} $R0 == -1 + ${ElseIf} $R0 = -1 StrCpy $R1 "$(newerVersionInstalled)" StrCpy $R2 "$(uninstallBeforeInstalling)" !if "${ALLOWDOWNGRADES}" == "true" @@ -232,7 +236,7 @@ Function PageReinstall nsDialogs::Create 1018 Pop $R4 - ${IfThen} $(^RTL) == 1 ${|} nsDialogs::SetRTL $(^RTL) ${|} + ${IfThen} $(^RTL) = 1 ${|} nsDialogs::SetRTL $(^RTL) ${|} ${NSD_CreateLabel} 0 0 100% 24u $R1 Pop $R1 @@ -245,14 +249,14 @@ Function PageReinstall Pop $R3 ; Disable this radio button if downgrading and downgrades are disabled !if "${ALLOWDOWNGRADES}" == "false" - ${IfThen} $R0 == -1 ${|} EnableWindow $R3 0 ${|} + ${IfThen} $R0 = -1 ${|} EnableWindow $R3 0 ${|} !endif ${NSD_OnClick} $R3 PageReinstallUpdateSelection ; Check the first radio button if this the first time ; we enter this page or if the second button wasn't ; selected the last time we were on this page - ${If} $ReinstallPageCheck != 2 + ${If} $ReinstallPageCheck <> 2 SendMessage $R2 ${BM_SETCHECK} ${BST_CHECKED} 0 ${Else} SendMessage $R3 ${BM_SETCHECK} ${BST_CHECKED} 0 @@ -291,7 +295,11 @@ Function PageLeaveReinstall ${Else} ReadRegStr $4 SHCTX "${MANUPRODUCTKEY}" "" ReadRegStr $R1 SHCTX "${UNINSTKEY}" "UninstallString" - ExecWait '$R1 /P _?=$4' $0 + ${If} $UpdateMode = 1 + ExecWait '$R1 /UPDATE /P _?=$4' $0 + ${Else} + ExecWait '$R1 /P _?=$4' $0 + ${EndIf} ${EndIf} BringToFront @@ -339,7 +347,7 @@ Var AppStartMenuFolder !define MUI_FINISHPAGE_SHOWREADME_FUNCTION CreateDesktopShortcut ; Show run app after installation. !define MUI_FINISHPAGE_RUN "$INSTDIR\${MAINBINARYNAME}.exe" -!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive +!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassiveButUpdateShortcutIfUpdate !insertmacro MUI_PAGE_FINISH ; Uninstaller Pages @@ -350,7 +358,7 @@ Var DeleteAppDataCheckboxState !define MUI_PAGE_CUSTOMFUNCTION_SHOW un.ConfirmShow Function un.ConfirmShow ; Add add a `Delete app data` check box FindWindow $1 "#32770" "" $HWNDPARENT ; Find inner dialog - ${If} $(^RTL) == 1 + ${If} $(^RTL) = 1 System::Call 'USER32::CreateWindowEx(i${__NSD_CheckBox_EXSTYLE}|${WS_EX_LAYOUTRTL},t"${__NSD_CheckBox_CLASS}",t "$(deleteAppData)",i${__NSD_CheckBox_STYLE},i 50,i 100,i 400, i 25,i$1,i0,i0,i0)i.s' ${Else} System::Call 'USER32::CreateWindowEx(i${__NSD_CheckBox_EXSTYLE},t"${__NSD_CheckBox_CLASS}",t "$(deleteAppData)",i${__NSD_CheckBox_STYLE},i 0,i 100,i 400, i 25,i$1,i0,i0,i0)i.s' @@ -377,13 +385,15 @@ FunctionEnd !include "{{this}}" {{/each}} -Var PassiveMode -Var UpdateMode Function .onInit ${GetOptions} $CMDLINE "/P" $PassiveMode IfErrors +2 0 StrCpy $PassiveMode 1 + ${GetOptions} $CMDLINE "/NS" $NoShortcutMode + IfErrors +2 0 + StrCpy $NoShortcutMode 1 + ${GetOptions} $CMDLINE "/UPDATE" $UpdateMode IfErrors +2 0 StrCpy $UpdateMode 1 @@ -427,9 +437,9 @@ Section EarlyChecks !if "${ALLOWDOWNGRADES}" == "false" IfSilent 0 silent_downgrades_done ; If downgrading - ${If} $R0 == -1 + ${If} $R0 = -1 System::Call 'kernel32::AttachConsole(i -1)i.r0' - ${If} $0 != 0 + ${If} $0 <> 0 System::Call 'kernel32::GetStdHandle(i -11)i.r0' System::call 'kernel32::SetConsoleTextAttribute(i r0, i 0x0004)' ; set red color FileWrite $0 "$(silentDowngrades)" @@ -462,7 +472,7 @@ Section WebView2 DetailPrint "$(webview2Downloading)" NSISdl::download "https://go.microsoft.com/fwlink/p/?LinkId=2124703" "$TEMP\MicrosoftEdgeWebview2Setup.exe" Pop $0 - ${If} $0 == 0 + ${If} $0 = 0 DetailPrint "$(webview2DownloadSuccess)" ${Else} DetailPrint "$(webview2DownloadError)" @@ -494,7 +504,7 @@ Section WebView2 DetailPrint "$(installingWebview2)" ; $6 holds the path to the webview2 installer ExecWait "$6 ${WEBVIEW2INSTALLERARGS} /install" $1 - ${If} $1 == 0 + ${If} $1 = 0 DetailPrint "$(webview2InstallSuccess)" ${Else} DetailPrint "$(webview2InstallError)" @@ -567,40 +577,32 @@ Section Install WriteRegDWORD SHCTX "${UNINSTKEY}" "NoRepair" "1" WriteRegDWORD SHCTX "${UNINSTKEY}" "EstimatedSize" "${ESTIMATEDSIZE}" - ; Create start menu shortcut (GUI) + ; Create start menu shortcut !insertmacro MUI_STARTMENU_WRITE_BEGIN Application Call CreateStartMenuShortcut !insertmacro MUI_STARTMENU_WRITE_END - ; Create shortcuts for silent and passive installers, which - ; can be disabled by passing `/NS` or `/UPDATE` flag. - ; - ; GUI installer has buttons for users to control creating them. - IfSilent check_ns_flag 0 - ${IfThen} $PassiveMode == 1 ${|} Goto check_ns_flag ${|} - Goto shortcuts_done - check_ns_flag: - ${GetOptions} $CMDLINE "/NS" $R0 - IfErrors 0 shortcuts_done - ${If} $UpdateMode <> 1 - Call CreateDesktopShortcut - Call CreateStartMenuShortcut - ${EndIf} - shortcuts_done: + ; Create desktop shortcut for silent and passive installers + ; because finish page will be skipped + IfSilent create_shortcut 0 + StrCmp $PassiveMode "1" create_shortcut shortcut_done + create_shortcut: + Call CreateDesktopShortcut + shortcut_done: !ifdef NSIS_HOOK_POSTINSTALL !insertmacro "${NSIS_HOOK_POSTINSTALL}" !endif ; Auto close this page for passive mode - ${IfThen} $PassiveMode == 1 ${|} SetAutoClose true ${|} + ${IfThen} $PassiveMode = 1 ${|} SetAutoClose true ${|} SectionEnd Function .onInstSuccess ; Check for `/R` flag only in silent and passive installers because ; GUI installer has a toggle for the user to (re)start the app IfSilent check_r_flag 0 - ${IfThen} $PassiveMode == 1 ${|} Goto check_r_flag ${|} + ${IfThen} $PassiveMode = 1 ${|} Goto check_r_flag ${|} Goto run_done check_r_flag: ${GetOptions} $CMDLINE "/R" $R0 @@ -618,12 +620,13 @@ Function un.onInit !endif !insertmacro MUI_UNGETLANGUAGE -FunctionEnd -Section Uninstall ${GetOptions} $CMDLINE "/UPDATE" $UpdateMode IfErrors +2 0 StrCpy $UpdateMode 1 +FunctionEnd + +Section Uninstall !insertmacro CheckIfAppIsRunning @@ -675,13 +678,13 @@ Section Uninstall ; Remove start menu shortcut !insertmacro MUI_STARTMENU_GETFOLDER Application $AppStartMenuFolder - !insertmacro UnpinShortcut "$SMPROGRAMS\$AppStartMenuFolder\${MAINBINARYNAME}.lnk" - Delete "$SMPROGRAMS\$AppStartMenuFolder\${MAINBINARYNAME}.lnk" + !insertmacro UnpinShortcut "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" + Delete "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" RMDir "$SMPROGRAMS\$AppStartMenuFolder" ; Remove desktop shortcuts - !insertmacro UnpinShortcut "$DESKTOP\${MAINBINARYNAME}.lnk" - Delete "$DESKTOP\${MAINBINARYNAME}.lnk" + !insertmacro UnpinShortcut "$DESKTOP\${PRODUCTNAME}.lnk" + Delete "$DESKTOP\${PRODUCTNAME}.lnk" ${EndIf} ; Remove registry information for add/remove programs @@ -721,16 +724,46 @@ Function RestorePreviousInstallLocation FunctionEnd Function SkipIfPassive - ${IfThen} $PassiveMode == 1 ${|} Abort ${|} + ${IfThen} $PassiveMode = 1 ${|} Abort ${|} +FunctionEnd + +Function SkipIfPassiveButUpdateShortcutIfUpdate + ${If} $PassiveMode = 1 + Call CreateDesktopShortcut + Abort + ${EndIf} FunctionEnd Function CreateDesktopShortcut - CreateShortcut "$DESKTOP\${MAINBINARYNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" - !insertmacro SetLnkAppUserModelId "$DESKTOP\${MAINBINARYNAME}.lnk" + ; Skip creating shortcut if in update mode + ; and shortcuts doesn't exist, which means user deleted it + ; so we respect that. + ${If} $UpdateMode = 1 + IfFileExists "$DESKTOP\${PRODUCTNAME}.lnk" +2 0 + Return + ${EndIf} + + ${If} $NoShortcutMode = 1 + Return + ${EndIf} + + CreateShortcut "$DESKTOP\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" + !insertmacro SetLnkAppUserModelId "$DESKTOP\${PRODUCTNAME}.lnk" FunctionEnd Function CreateStartMenuShortcut + ; Skip creating shortcut if in update mode. + ; See `CreateDesktopShortcut` above. + ${If} $UpdateMode = 1 + IfFileExists "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" +2 0 + Return + ${EndIf} + + ${If} $NoShortcutMode = 1 + Return + ${EndIf} + CreateDirectory "$SMPROGRAMS\$AppStartMenuFolder" - CreateShortcut "$SMPROGRAMS\$AppStartMenuFolder\${MAINBINARYNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" - !insertmacro SetLnkAppUserModelId "$SMPROGRAMS\$AppStartMenuFolder\${MAINBINARYNAME}.lnk" + CreateShortcut "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe" + !insertmacro SetLnkAppUserModelId "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" FunctionEnd