Ver Fonte

fix(nsis): migrate old shortcuts by setting the path only instead of re-creating a new one (#9915)

Tony há 1 ano atrás
pai
commit
ea78bf5558

+ 5 - 0
.changes/nsis-migrate-shortcut.md

@@ -0,0 +1,5 @@
+---
+"tauri-bundler": "patch:enhance"
+---
+
+For NSIS installer, migrate old shortcuts by setting the path only instead of re-creating a new one

+ 54 - 49
tooling/bundler/src/bundle/windows/templates/installer.nsi

@@ -344,10 +344,10 @@ Var AppStartMenuFolder
 ; Use show readme button in the finish page as a button create a desktop shortcut
 !define MUI_FINISHPAGE_SHOWREADME
 !define MUI_FINISHPAGE_SHOWREADME_TEXT "$(createDesktop)"
-!define MUI_FINISHPAGE_SHOWREADME_FUNCTION CreateDesktopShortcut
+!define MUI_FINISHPAGE_SHOWREADME_FUNCTION CreateOrUpdateDesktopShortcut
 ; Show run app after installation.
 !define MUI_FINISHPAGE_RUN "$INSTDIR\${MAINBINARYNAME}.exe"
-!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassiveButUpdateShortcutIfUpdate
+!define MUI_PAGE_CUSTOMFUNCTION_PRE SkipIfPassive
 !insertmacro MUI_PAGE_FINISH
 
 ; Uninstaller Pages
@@ -387,16 +387,19 @@ FunctionEnd
 
 Function .onInit
   ${GetOptions} $CMDLINE "/P" $PassiveMode
-  IfErrors +2 0
+  ${IfNot} ${Errors}
     StrCpy $PassiveMode 1
+  ${EndIf}
 
   ${GetOptions} $CMDLINE "/NS" $NoShortcutMode
-  IfErrors +2 0
+  ${IfNot} ${Errors}
     StrCpy $NoShortcutMode 1
+  ${EndIf}
 
   ${GetOptions} $CMDLINE "/UPDATE" $UpdateMode
-  IfErrors +2 0
+  ${IfNot} ${Errors}
     StrCpy $UpdateMode 1
+  ${EndIf}
 
   !if "${DISPLAYLANGUAGESELECTOR}" == "true"
     !insertmacro MUI_LANGDLL_DISPLAY
@@ -435,7 +438,7 @@ FunctionEnd
 Section EarlyChecks
   ; Abort silent installer if downgrades is disabled
   !if "${ALLOWDOWNGRADES}" == "false"
-  IfSilent 0 silent_downgrades_done
+  ${If} ${Silent}
     ; If downgrading
     ${If} $R0 = -1
       System::Call 'kernel32::AttachConsole(i -1)i.r0'
@@ -446,7 +449,7 @@ Section EarlyChecks
       ${EndIf}
       Abort
     ${EndIf}
-  silent_downgrades_done:
+  ${EndIf}
   !endif
 
 SectionEnd
@@ -579,37 +582,37 @@ Section Install
 
   ; Create start menu shortcut
   !insertmacro MUI_STARTMENU_WRITE_BEGIN Application
-    Call CreateStartMenuShortcut
+    Call CreateOrUpdateStartMenuShortcut
   !insertmacro MUI_STARTMENU_WRITE_END
 
   ; 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:
+  ${If} $PassiveMode = 1
+  ${OrIf} ${Silent}
+    Call CreateOrUpdateDesktopShortcut
+  ${EndIf}
 
   !ifdef NSIS_HOOK_POSTINSTALL
     !insertmacro "${NSIS_HOOK_POSTINSTALL}"
   !endif
 
   ; Auto close this page for passive mode
-  ${IfThen} $PassiveMode = 1 ${|} SetAutoClose true ${|}
+  ${If} $PassiveMode = 1
+    SetAutoClose true
+  ${EndIf}
 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 ${|}
-  Goto run_done
-  check_r_flag:
+  ${If} $PassiveMode = 1
+  ${OrIf} ${Silent}
     ${GetOptions} $CMDLINE "/R" $R0
-    IfErrors run_done 0
+    ${IfNot} ${Errors}
       ${GetOptions} $CMDLINE "/ARGS" $R0
       Exec '"$INSTDIR\${MAINBINARYNAME}.exe" $R0'
-  run_done:
+    ${EndIf}
+  ${EndIf}
 FunctionEnd
 
 Function un.onInit
@@ -621,9 +624,15 @@ Function un.onInit
 
   !insertmacro MUI_UNGETLANGUAGE
 
+  ${GetOptions} $CMDLINE "/P" $PassiveMode
+  ${IfNot} ${Errors}
+    StrCpy $PassiveMode 1
+  ${EndIf}
+
   ${GetOptions} $CMDLINE "/UPDATE" $UpdateMode
-  IfErrors +2 0
+  ${IfNot} ${Errors}
     StrCpy $UpdateMode 1
+  ${EndIf}
 FunctionEnd
 
 Section Uninstall
@@ -712,9 +721,9 @@ Section Uninstall
   !endif
 
   ; Auto close if passive mode
-  ${GetOptions} $CMDLINE "/P" $R0
-  IfErrors +2 0
+  ${If} $PassiveMode = 1
     SetAutoClose true
+  ${EndIf}
 SectionEnd
 
 Function RestorePreviousInstallLocation
@@ -727,43 +736,39 @@ Function SkipIfPassive
   ${IfThen} $PassiveMode = 1  ${|} Abort ${|}
 FunctionEnd
 
-Function SkipIfPassiveButUpdateShortcutIfUpdate
-  ${If} $PassiveMode = 1
-    Call CreateDesktopShortcut
-    Abort
+Function CreateOrUpdateStartMenuShortcut
+  ; We used to use product name as MAINBINARYNAME
+  ; migrate old shortcuts to target the new MAINBINARYNAME
+  ${If} ${FileExists} "$DESKTOP\${PRODUCTNAME}.lnk"
+    !insertmacro SetShortcutTarget "$DESKTOP\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe"
+    Return
   ${EndIf}
-FunctionEnd
 
-Function CreateDesktopShortcut
-  ; Skip creating shortcut if in update mode
-  ; and shortcuts doesn't exist, which means user deleted it
-  ; so we respect that.
+  ; Skip creating shortcut if in update mode or no shortcut mode
   ${If} $UpdateMode = 1
-    IfFileExists "$DESKTOP\${PRODUCTNAME}.lnk" +2 0
-      Return
-  ${EndIf}
-
-  ${If} $NoShortcutMode = 1
+  ${OrIf} $NoShortcutMode = 1
     Return
   ${EndIf}
 
-  CreateShortcut "$DESKTOP\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe"
-  !insertmacro SetLnkAppUserModelId "$DESKTOP\${PRODUCTNAME}.lnk"
+  CreateDirectory "$SMPROGRAMS\$AppStartMenuFolder"
+  CreateShortcut "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe"
+  !insertmacro SetLnkAppUserModelId "$SMPROGRAMS\$AppStartMenuFolder\${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
+Function CreateOrUpdateDesktopShortcut
+  ; We used to use product name as MAINBINARYNAME
+  ; migrate old shortcuts to target the new MAINBINARYNAME
+  ${If} ${FileExists} "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk"
+    !insertmacro SetShortcutTarget "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe"
+    Return
   ${EndIf}
 
-  ${If} $NoShortcutMode = 1
+  ; Skip creating shortcut if in update mode or no shortcut mode
+  ${If} $UpdateMode = 1
+  ${OrIf} $NoShortcutMode = 1
     Return
   ${EndIf}
 
-  CreateDirectory "$SMPROGRAMS\$AppStartMenuFolder"
-  CreateShortcut "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe"
-  !insertmacro SetLnkAppUserModelId "$SMPROGRAMS\$AppStartMenuFolder\${PRODUCTNAME}.lnk"
+  CreateShortcut "$DESKTOP\${PRODUCTNAME}.lnk" "$INSTDIR\${MAINBINARYNAME}.exe"
+  !insertmacro SetLnkAppUserModelId "$DESKTOP\${PRODUCTNAME}.lnk"
 FunctionEnd

+ 15 - 0
tooling/bundler/src/bundle/windows/templates/utils.nsh

@@ -116,3 +116,18 @@
       ${IUnknown::Release} $0 ""
   ${EndIf}
 !macroend
+
+; Set target path for a .lnk shortcut
+!macro SetShortcutTarget shortcut target
+  !insertmacro ComHlpr_CreateInProcInstance ${CLSID_ShellLink} ${IID_IShellLink} r0 ""
+  ${If} $0 P<> 0
+    ${IUnknown::QueryInterface} $0 '("${IID_IPersistFile}",.r1)'
+    ${If} $1 P<> 0
+      ${IPersistFile::Load} $1 '("${shortcut}", ${STGM_READWRITE})'
+      ${IShellLink::SetPath} $0 '(w "${target}")'
+      ${IPersistFile::Save} $1 '("${shortcut}",1)'
+      ${IUnknown::Release} $1 ""
+    ${EndIf}
+    ${IUnknown::Release} $0 ""
+  ${EndIf}
+!macroend