From 03e07fffbd2b7dd591fad17856d3d412c6cbb01f Mon Sep 17 00:00:00 2001 From: Robert Strong Date: Wed, 9 Feb 2011 11:48:56 -0800 Subject: [PATCH] Main patch for Bug 621873 - Pin to taskbar when setting as default browser on Windows 7. r=jmathies, a=approval2.0 --- browser/installer/windows/nsis/installer.nsi | 157 ++-- browser/installer/windows/nsis/shared.nsh | 209 ++++- .../installer/windows/nsis/uninstaller.nsi | 2 + .../mozapps/installer/windows/nsis/common.nsh | 764 ++++++++++++++---- .../installer/windows/nsis/makensis.mk | 1 + 5 files changed, 903 insertions(+), 230 deletions(-) diff --git a/browser/installer/windows/nsis/installer.nsi b/browser/installer/windows/nsis/installer.nsi index 4eae43606c75..42cd9b3a9967 100755 --- a/browser/installer/windows/nsis/installer.nsi +++ b/browser/installer/windows/nsis/installer.nsi @@ -108,10 +108,12 @@ VIAddVersionKey "OriginalFilename" "setup.exe" !insertmacro GetPathFromString !insertmacro GetParent !insertmacro IsHandlerForInstallDir +!insertmacro IsPinnedToTaskBar !insertmacro LogDesktopShortcut !insertmacro LogQuickLaunchShortcut !insertmacro LogStartMenuShortcut !insertmacro ManualCloseAppPrompt +!insertmacro PinnedToStartMenuLnkCount !insertmacro RegCleanAppHandler !insertmacro RegCleanMain !insertmacro RegCleanUninstall @@ -279,7 +281,12 @@ Section "-Application" APP_IDX ; Default for creating Quick Launch shortcut (1 = create, 0 = don't create) ${If} $AddQuickLaunchSC == "" - StrCpy $AddQuickLaunchSC "1" + ; Don't install the quick launch shortcut on Windows 7 + ${If} ${AtLeastWin7} + StrCpy $AddQuickLaunchSC "0" + ${Else} + StrCpy $AddQuickLaunchSC "1" + ${EndIf} ${EndIf} ; Default for creating Desktop shortcut (1 = create, 0 = don't create) @@ -348,12 +355,12 @@ Section "-Application" APP_IDX ${SetStartMenuInternet} ${FixShellIconHandler} - ; If we are writing to HKLM and create the quick launch and the desktop + ; If we are writing to HKLM and create either the desktop or start menu ; shortcuts set IconsVisible to 1 otherwise to 0. ${StrFilter} "${FileMainEXE}" "+" "" "" $R9 StrCpy $0 "Software\Clients\StartMenuInternet\$R9\InstallInfo" - ${If} $AddQuickLaunchSC == 1 - ${OrIf} $AddDesktopSC == 1 + ${If} $AddDesktopSC == 1 + ${OrIf} $AddStartMenuSC == 1 WriteRegDWORD HKLM "$0" "IconsVisible" 1 ${Else} WriteRegDWORD HKLM "$0" "IconsVisible" 0 @@ -392,45 +399,80 @@ Section "-Application" APP_IDX ${LogQuickLaunchShortcut} "${BrandFullName}.lnk" ${LogDesktopShortcut} "${BrandFullName}.lnk" + ; Best effort to update the Win7 taskbar and start menu shortcut app model + ; id's. The possible contexts are current user / system and the user that + ; elevated the installer. + Call FixShortcutAppModelIDs + ; If the current context is all also perform Win7 taskbar and start menu link + ; maintenance for the current user context. + ${If} $TmpVal == "HKLM" + SetShellVarContext current ; Set SHCTX to HKCU + Call FixShortcutAppModelIDs + SetShellVarContext all ; Set SHCTX to HKLM + ${EndIf} + + ; If running elevated also perform Win7 taskbar and start menu link + ; maintenance for the unelevated user context in case that is different than + ; the current user. + ClearErrors + ${GetParameters} $0 + ${GetOptions} "$0" "/UAC:" $0 + ${Unless} ${Errors} + GetFunctionAddress $0 FixShortcutAppModelIDs + UAC::ExecCodeSegment $0 + ${EndIf} + ; UAC only allows elevating to an Admin account so there is no need to add ; the Start Menu or Desktop shortcuts from the original unelevated process ; since this will either add it for the user if unelevated or All Users if ; elevated. ${If} $AddStartMenuSC == 1 - CreateShortCut "$SMPROGRAMS\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" \ - "" "$INSTDIR\${FileMainEXE}" 0 - ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \ + CreateShortCut "$SMPROGRAMS\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk" + ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \ "$INSTDIR" - ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" "${AppUserModelID}" - ${LogMsg} "Added Shortcut: $SMPROGRAMS\$StartMenuDir\${BrandFullName}.lnk" + ${If} ${AtLeastWin7} + ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" "${AppUserModelID}" + ${EndIf} + ${LogMsg} "Added Shortcut: $SMPROGRAMS\${BrandFullName}.lnk" + ${Else} + ${LogMsg} "** ERROR Adding Shortcut: $SMPROGRAMS\${BrandFullName}.lnk" + ${EndIf} ${EndIf} ${If} $AddDesktopSC == 1 - CreateShortCut "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" \ - "" "$INSTDIR\${FileMainEXE}" 0 - ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandFullName}.lnk" \ - "$INSTDIR" - ApplicationID::Set "$DESKTOP\${BrandFullName}.lnk" "${AppUserModelID}" - ${LogMsg} "Added Shortcut: $DESKTOP\${BrandFullName}.lnk" + CreateShortCut "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$DESKTOP\${BrandFullName}.lnk" + ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandFullName}.lnk" \ + "$INSTDIR" + ${If} ${AtLeastWin7} + ApplicationID::Set "$DESKTOP\${BrandFullName}.lnk" "${AppUserModelID}" + ${EndIf} + ${LogMsg} "Added Shortcut: $DESKTOP\${BrandFullName}.lnk" + ${Else} + ${LogMsg} "** ERROR Adding Shortcut: $DESKTOP\${BrandFullName}.lnk" + ${EndIf} ${EndIf} ; If elevated the Quick Launch shortcut must be added from the unelevated ; original process. ${If} $AddQuickLaunchSC == 1 - ClearErrors - ${GetParameters} $0 - ${GetOptions} "$0" "/UAC:" $0 - ${If} ${Errors} - Call AddQuickLaunchShortcut - ${LogMsg} "Added Shortcut: $QUICKLAUNCH\${BrandFullName}.lnk" - ${Else} - ; It is not possible to add a log entry from the unelevated process so - ; add the log entry without the path since there is no simple way to know - ; the correct full path. - ${LogMsg} "Added Quick Launch Shortcut: ${BrandFullName}.lnk" - GetFunctionAddress $0 AddQuickLaunchShortcut - UAC::ExecCodeSegment $0 - ${EndIf} + ${Unless} ${AtLeastWin7} + ClearErrors + ${GetParameters} $0 + ${GetOptions} "$0" "/UAC:" $0 + ${If} ${Errors} + Call AddQuickLaunchShortcut + ${LogMsg} "Added Shortcut: $QUICKLAUNCH\${BrandFullName}.lnk" + ${Else} + ; It is not possible to add a log entry from the unelevated process so + ; add the log entry without the path since there is no simple way to + ; know the correct full path. + ${LogMsg} "Added Quick Launch Shortcut: ${BrandFullName}.lnk" + GetFunctionAddress $0 AddQuickLaunchShortcut + UAC::ExecCodeSegment $0 + ${EndIf} + ${EndUnless} ${EndIf} SectionEnd @@ -456,11 +498,14 @@ Section "-InstallEndCleanup" ${EndIf} ${EndUnless} - ; Win7 taskbar and start menu link maintenance - ${UpdateShortcutAppModelIDs} "$INSTDIR\${FileMainEXE}" "${AppUserModelID}" $0 + ; Adds a pinned Task Bar shortcut (see MigrateTaskBarShortcut for details). + ${MigrateTaskBarShortcut} + + ${GetShortcutsLogPath} $0 + WriteIniStr "$0" "TASKBAR" "Migrated" "true" ; Refresh desktop icons - System::Call "shell32::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)" + System::Call "shell32::SHChangeNotify(i 0x08000000, i 0, i 0, i 0)" ${InstallEndCleanupCommon} @@ -565,11 +610,11 @@ FunctionEnd # Helper Functions Function AddQuickLaunchShortcut - CreateShortCut "$QUICKLAUNCH\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" \ - "" "$INSTDIR\${FileMainEXE}" 0 - ShellLink::SetShortCutWorkingDirectory "$QUICKLAUNCH\${BrandFullName}.lnk" \ - "$INSTDIR" - ApplicationID::Set "$QUICKLAUNCH\${BrandFullName}.lnk" "${AppUserModelID}" + CreateShortCut "$QUICKLAUNCH\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk" + ShellLink::SetShortCutWorkingDirectory "$QUICKLAUNCH\${BrandFullName}.lnk" \ + "$INSTDIR" + ${EndIf} FunctionEnd Function CheckExistingInstall @@ -736,7 +781,10 @@ Function leaveShortcuts ${EndIf} ${MUI_INSTALLOPTIONS_READ} $AddDesktopSC "shortcuts.ini" "Field 2" "State" ${MUI_INSTALLOPTIONS_READ} $AddStartMenuSC "shortcuts.ini" "Field 3" "State" - ${MUI_INSTALLOPTIONS_READ} $AddQuickLaunchSC "shortcuts.ini" "Field 4" "State" + ; Don't install the quick launch shortcut on Windows 7 + ${Unless} ${AtLeastWin7} + ${MUI_INSTALLOPTIONS_READ} $AddQuickLaunchSC "shortcuts.ini" "Field 4" "State" + ${EndUnless} ${If} $InstallType == ${INSTALLTYPE_CUSTOM} Call CheckExistingInstall @@ -791,9 +839,14 @@ Function preSummary WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" "Write Test" ${Unless} ${Errors} DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" - ; Check if Firefox is already the handler for http. This is set on all - ; versions of Windows. + ; Check if Firefox is the http handler for this user. + SetShellVarContext current ; Set SHCTX to the current user ${IsHandlerForInstallDir} "http" $R9 + ${If} $TmpVal == "HKLM" + SetShellVarContext all ; Set SHCTX to all users + ${EndIf} + ; If Firefox isn't the http handler for this user show the option to set + ; Firefox as the default browser. ${If} "$R9" != "true" WriteINIStr "$PLUGINSDIR\summary.ini" "Settings" NumFields "4" WriteINIStr "$PLUGINSDIR\summary.ini" "Field 4" Type "checkbox" @@ -916,7 +969,12 @@ Function .onInit WriteINIStr "$PLUGINSDIR\options.ini" "Field 5" Bottom "87" ; Setup the shortcuts.ini file for the Custom Shortcuts Page - WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Settings" NumFields "4" + ; Don't offer to install the quick launch shortcut on Windows 7 + ${If} ${AtLeastWin7} + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Settings" NumFields "3" + ${Else} + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Settings" NumFields "4" + ${EndIf} WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 1" Type "label" WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 1" Text "$(CREATE_ICONS_DESC)" @@ -942,13 +1000,16 @@ Function .onInit WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 3" Bottom "50" WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 3" State "1" - WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Type "checkbox" - WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Text "$(ICONS_QUICKLAUNCH)" - WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Left "15" - WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Right "-1" - WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Top "60" - WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Bottom "70" - WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" State "1" + ; Don't offer to install the quick launch shortcut on Windows 7 + ${Unless} ${AtLeastWin7} + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Type "checkbox" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Text "$(ICONS_QUICKLAUNCH)" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Left "15" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Right "-1" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Top "60" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" Bottom "70" + WriteINIStr "$PLUGINSDIR\shortcuts.ini" "Field 4" State "1" + ${EndUnless} ; There must always be a core directory. ${GetSize} "$EXEDIR\core\" "/S=0K" $R5 $R7 $R8 diff --git a/browser/installer/windows/nsis/shared.nsh b/browser/installer/windows/nsis/shared.nsh index 9b063a99b065..a0ab65263b5a 100755 --- a/browser/installer/windows/nsis/shared.nsh +++ b/browser/installer/windows/nsis/shared.nsh @@ -44,6 +44,8 @@ ${RegCleanMain} "Software\Mozilla" ${RegCleanUninstall} ${UpdateProtocolHandlers} + ; Win7 taskbar and start menu link maintenance + Call FixShortcutAppModelIDs ClearErrors WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" "Write Test" @@ -59,6 +61,9 @@ ${FixShellIconHandler} ${SetAppLSPCategories} ${LSP_CATEGORIES} + ; Win7 taskbar and start menu link maintenance + Call FixShortcutAppModelIDs + ; Only update the Clients\StartMenuInternet registry key values if they ; don't exist or this installation is the same as the one set in those keys. ${StrFilter} "${FileMainEXE}" "+" "" "" $1 @@ -82,15 +87,15 @@ ; root of the Start Menu Programs directory. ${MigrateStartMenuShortcut} + ; Adds a pinned Task Bar shortcut (see MigrateTaskBarShortcut for details). + ${MigrateTaskBarShortcut} + ${RemoveDeprecatedKeys} ${SetAppKeys} ${FixClassKeys} ${SetUninstallKeys} - ; Win7 taskbar and start menu link maintenance - ${UpdateShortcutAppModelIDs} "$INSTDIR\${FileMainEXE}" "${AppUserModelID}" $0 - ; Remove files that may be left behind by the application in the ; VirtualStore directory. ${CleanVirtualStore} @@ -119,6 +124,7 @@ ${StrFilter} "${FileMainEXE}" "+" "" "" $0 StrCpy $R1 "Software\Clients\StartMenuInternet\$0\InstallInfo" WriteRegDWORD HKLM "$R1" "IconsVisible" 0 + SetShellVarContext all ; Set $DESKTOP to All Users ${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk" SetShellVarContext current ; Set $DESKTOP to the current user's desktop @@ -180,48 +186,61 @@ SetShellVarContext all ; Set $DESKTOP to All Users ${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk" - CreateShortCut "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" \ - "" "$INSTDIR\${FileMainEXE}" 0 - ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR" - ApplicationID::Set "$DESKTOP\${BrandFullName}.lnk" "${AppUserModelID}" - ${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk" + CreateShortCut "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$DESKTOP\${BrandFullName}.lnk" + ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR" + ${If} ${AtLeastWin7} + ApplicationID::Set "$DESKTOP\${BrandFullName}.lnk" "${AppUserModelID}" + ${EndIf} + ${Else} SetShellVarContext current ; Set $DESKTOP to the current user's desktop ${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk" - CreateShortCut "$DESKTOP\${BrandFullName}.lnk" \ - "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0 - ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandFullName}.lnk" \ - "$INSTDIR" - ApplicationID::Set "$DESKTOP\${BrandFullName}.lnk" "${AppUserModelID}" + CreateShortCut "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$DESKTOP\${BrandFullName}.lnk" + ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandFullName}.lnk" \ + "$INSTDIR" + ${If} ${AtLeastWin7} + ApplicationID::Set "$DESKTOP\${BrandFullName}.lnk" "${AppUserModelID}" + ${EndIf} + ${EndIf} ${EndUnless} - ${EndUnless} + ${EndIf} ${EndUnless} - SetShellVarContext all ; Set $DESKTOP to All Users + SetShellVarContext all ; Set $SMPROGRAMS to All Users ${Unless} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk" - CreateShortCut "$SMPROGRAMS\${BrandFullName}.lnk" \ - "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0 - ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \ - "$INSTDIR" - ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" "${AppUserModelID}" - ${Unless} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk" + CreateShortCut "$SMPROGRAMS\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk" + ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \ + "$INSTDIR" + ${If} ${AtLeastWin7} + ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" "${AppUserModelID}" + ${EndIf} + ${Else} SetShellVarContext current ; Set $SMPROGRAMS to the current user's Start ; Menu Programs directory ${Unless} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk" - CreateShortCut "$SMPROGRAMS\${BrandFullName}.lnk" \ - "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0 - ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \ - "$INSTDIR" - ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" "${AppUserModelID}" + CreateShortCut "$SMPROGRAMS\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk" + ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \ + "$INSTDIR" + ${If} ${AtLeastWin7} + ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" "${AppUserModelID}" + ${EndIf} + ${EndIf} ${EndUnless} - ${EndUnless} + ${EndIf} ${EndUnless} - ${Unless} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk" + ; Windows 7 doesn't use the QuickLaunch directory + ${Unless} ${AtLeastWin7} + ${AndUnless} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk" CreateShortCut "$QUICKLAUNCH\${BrandFullName}.lnk" \ - "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0 - ShellLink::SetShortCutWorkingDirectory "$QUICKLAUNCH\${BrandFullName}.lnk" \ - "$INSTDIR" - ApplicationID::Set "$QUICKLAUNCH\${BrandFullName}.lnk" "${AppUserModelID}" + "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk" + ShellLink::SetShortCutWorkingDirectory "$QUICKLAUNCH\${BrandFullName}.lnk" \ + "$INSTDIR" + ${EndIf} ${EndUnless} !macroend !define ShowShortcuts "!insertmacro ShowShortcuts" @@ -662,6 +681,110 @@ !macroend !define RemoveDeprecatedFiles "!insertmacro RemoveDeprecatedFiles" +; Adds a pinned shortcut to Task Bar on update for Windows 7 and above if this +; macro has never been called before and the application is default (see +; PinToTaskBar for more details). +!macro MigrateTaskBarShortcut + ${GetShortcutsLogPath} $0 + ${If} ${FileExists} "$0" + ClearErrors + ReadINIStr $1 "$0" "TASKBAR" "Migrated" + ${If} ${Errors} + ClearErrors + WriteIniStr "$0" "TASKBAR" "Migrated" "true" + ${If} ${AtLeastWin7} + ; Check if the Firefox is the http handler for this user + SetShellVarContext current ; Set SHCTX to the current user + ${IsHandlerForInstallDir} "http" $R9 + ${If} $TmpVal == "HKLM" + SetShellVarContext all ; Set SHCTX to all users + ${EndIf} + ${If} "$R9" == "true" + ${PinToTaskBar} + ${EndIf} + ${EndIf} + ${EndIf} + ${EndIf} +!macroend +!define MigrateTaskBarShortcut "!insertmacro MigrateTaskBarShortcut" + +; Adds a pinned Task Bar shortcut on Windows 7 if there isn't one for the main +; application executable already. Existing pinned shortcuts for the same +; application model ID must be removed first to prevent breaking the pinned +; item's lists but multiple installations with the same application model ID is +; an edgecase. If removing existing pinned shortcuts with the same application +; model ID removes a pinned pinned Start Menu shortcut this will also add a +; pinned Start Menu shortcut. +!macro PinToTaskBar + ${If} ${AtLeastWin7} + StrCpy $8 "false" ; Whether a shortcut had to be created + ${IsPinnedToTaskBar} "$INSTDIR\${FileMainEXE}" $R9 + ${If} "$R9" == "false" + ; Find an existing Start Menu shortcut or create one to use for pinning + ${GetShortcutsLogPath} $0 + ${If} ${FileExists} "$0" + ClearErrors + ReadINIStr $1 "$0" "STARTMENU" "Shortcut0" + ${Unless} ${Errors} + SetShellVarContext all ; Set SHCTX to all users + ${Unless} ${FileExists} "$SMPROGRAMS\$1" + SetShellVarContext current ; Set SHCTX to the current user + ${Unless} ${FileExists} "$SMPROGRAMS\$1" + StrCpy $8 "true" + CreateShortCut "$SMPROGRAMS\$1" "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$SMPROGRAMS\$1" + ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\$1" \ + "$INSTDIR" + ApplicationID::Set "$SMPROGRAMS\$1" "${AppUserModelID}" + ${EndIf} + ${EndUnless} + ${EndUnless} + + ${If} ${FileExists} "$SMPROGRAMS\$1" + ; Count of Start Menu pinned shortcuts before unpinning. + ${PinnedToStartMenuLnkCount} $R9 + + ; Having multiple shortcuts pointing to different installations with + ; the same AppUserModelID (e.g. side by side installations of the + ; same version) will make the TaskBar shortcut's lists into an bad + ; state where the lists are not shown. To prevent this first + ; uninstall the pinned item. + ApplicationID::UninstallPinnedItem "$SMPROGRAMS\$1" + + ; Count of Start Menu pinned shortcuts after unpinning. + ${PinnedToStartMenuLnkCount} $R8 + + ; If there is a change in the number of Start Menu pinned shortcuts + ; assume that unpinning unpinned a side by side installation from + ; the Start Menu and pin this installation to the Start Menu. + ${Unless} $R8 == $R9 + ; Pin the shortcut to the Start Menu. 5381 is the shell32.dll + ; resource id for the "Pin to Start Menu" string. + InvokeShellVerb::DoIt "$SMPROGRAMS" "$1" "5381" + ${EndUnless} + + ; Pin the shortcut to the TaskBar. 5386 is the shell32.dll resource + ; id for the "Pin to Taskbar" string. + InvokeShellVerb::DoIt "$SMPROGRAMS" "$1" "5386" + + ; Delete the shortcut if it was created + ${If} "$8" == "true" + Delete "$SMPROGRAMS\$1" + ${EndIf} + ${EndIf} + + ${If} $TmpVal == "HKCU" + SetShellVarContext current ; Set SHCTX to the current user + ${Else} + SetShellVarContext all ; Set SHCTX to all users + ${EndIf} + ${EndUnless} + ${EndIf} + ${EndIf} + ${EndIf} +!macroend +!define PinToTaskBar "!insertmacro PinToTaskBar" + ; Adds a shortcut to the root of the Start Menu Programs directory if the ; application's Start Menu Programs directory exists with a shortcut pointing to ; this installation directory. This will also remove the old shortcuts and the @@ -689,12 +812,15 @@ Pop $4 ${If} "$INSTDIR\${FileMainEXE}" == "$4" CreateShortCut "$SMPROGRAMS\${BrandFullName}.lnk" \ - "$INSTDIR\${FileMainEXE}" "" \ - "$INSTDIR\${FileMainEXE}" 0 - ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \ - "$INSTDIR" - ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" \ - "${AppUserModelID}" + "$INSTDIR\${FileMainEXE}" + ${If} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk" + ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \ + "$INSTDIR" + ${If} ${AtLeastWin7} + ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" \ + "${AppUserModelID}" + ${EndIf} + ${EndIf} ${EndIf} ${EndIf} ${EndUnless} @@ -836,6 +962,13 @@ Function SetAsDefaultAppUserHKCU ${EndUnless} ${EndIf} ${RemoveDeprecatedKeys} + + ${PinToTaskBar} +FunctionEnd + +; Helper for updating the shortcut application model IDs. +Function FixShortcutAppModelIDs + ${UpdateShortcutAppModelIDs} "$INSTDIR\${FileMainEXE}" "${AppUserModelID}" $0 FunctionEnd ; The !ifdef NO_LOG prevents warnings when compiling the installer.nsi due to diff --git a/browser/installer/windows/nsis/uninstaller.nsi b/browser/installer/windows/nsis/uninstaller.nsi index c09f108e4a8b..2d615df197a1 100755 --- a/browser/installer/windows/nsis/uninstaller.nsi +++ b/browser/installer/windows/nsis/uninstaller.nsi @@ -93,9 +93,11 @@ VIAddVersionKey "OriginalFilename" "helper.exe" !insertmacro GetLongPath !insertmacro GetPathFromString !insertmacro IsHandlerForInstallDir +!insertmacro IsPinnedToTaskBar !insertmacro LogDesktopShortcut !insertmacro LogQuickLaunchShortcut !insertmacro LogStartMenuShortcut +!insertmacro PinnedToStartMenuLnkCount !insertmacro RegCleanAppHandler !insertmacro RegCleanMain !insertmacro RegCleanUninstall diff --git a/toolkit/mozapps/installer/windows/nsis/common.nsh b/toolkit/mozapps/installer/windows/nsis/common.nsh index a9915d099bf5..a7ada167fa11 100755 --- a/toolkit/mozapps/installer/windows/nsis/common.nsh +++ b/toolkit/mozapps/installer/windows/nsis/common.nsh @@ -113,6 +113,20 @@ !include /NONFATAL WinVer.nsh !endif +; Add Windows 7 / 2008 support for versions of WinVer.nsh that don't support +; them. This can be removed after bug 571381 is fixed. +!ifndef WINVER_7 + !define WINVER_7 0x601 + + !macro __MOZ__WinVer_DefineOSTests Test + !insertmacro __WinVer_DefineOSTest ${Test} 7 + !macroend + + !insertmacro __MOZ__WinVer_DefineOSTests AtLeast + !insertmacro __MOZ__WinVer_DefineOSTests Is + !insertmacro __MOZ__WinVer_DefineOSTests AtMost +!endif + !include x64.nsh ; NSIS provided macros that we have overridden. @@ -3256,10 +3270,11 @@ /** * Deletes shortcuts and Start Menu directories under Programs as specified by - * the shortcuts log ini file. The shortcuts will not be deleted if the shortcut - * target isn't for this install location which is determined by the shortcut - * having a target of $INSTDIR\${FileMainEXE}. The context (All Users or Current - * User) of the $DESKTOP, $STARTMENU, and $SMPROGRAMS constants depends on the + * the shortcuts log ini file and on Windows 7 unpins TaskBar and Start Menu + * shortcuts. The shortcuts will not be deleted if the shortcut target isn't for + * this install location which is determined by the shortcut having a target of + * $INSTDIR\${FileMainEXE}. The context (All Users or Current User) of the + * $DESKTOP and $SMPROGRAMS constants depends on the * SetShellVarContext setting and must be set by the caller of this macro. There * is no All Users context for $QUICKLAUNCH but this will not cause a problem * since the macro will just continue past the $QUICKLAUNCH shortcut deletion @@ -3294,12 +3309,16 @@ * Shortcut2=Mozilla App (Safe Mode).lnk * * $R4 = counter for appending to Shortcut for enumerating the ini file entries - * $R5 = return value from ShellLink::GetShortCutTarget - * $R6 = long path to the Start Menu Programs directory (e.g. $SMPROGRAMS) - * $R7 = return value from ReadINIStr for the relative path to the applications - * directory under the Start Menu Programs directory and the long path to - * this directory - * $R8 = return value from ReadINIStr for enumerating shortcuts + * $R5 = return value from ShellLink::GetShortCutTarget and + * ApplicationID::UninstallPinnedItem + * $R6 = find handle and the long path to the Start Menu Programs directory + * (e.g. $SMPROGRAMS) + * $R7 = path to the $QUICKLAUNCH\User Pinned directory and the return value + * from ReadINIStr for the relative path to the applications directory + * under the Start Menu Programs directory and the long path to this + * directory + * $R8 = return filename from FindFirst / FindNext and the return value from + * ReadINIStr for enumerating shortcuts * $R9 = long path to the shortcuts log ini file */ !macro DeleteShortcuts @@ -3324,89 +3343,163 @@ Push $R5 Push $R4 + ${If} ${AtLeastWin7} + ; Since shortcuts that are pinned can later be removed without removing + ; the pinned shortcut unpin the pinned shortcuts for the application's + ; main exe using the pinned shortcuts themselves. + StrCpy $R7 "$QUICKLAUNCH\User Pinned" + + ${If} ${FileExists} "$R7\TaskBar" + ; Delete TaskBar pinned shortcuts for the application's main exe + FindFirst $R6 $R8 "$R7\TaskBar\*.lnk" + ${Do} + ${If} ${FileExists} "$R7\TaskBar\$R8" + ShellLink::GetShortCutTarget "$R7\TaskBar\$R8" + Pop $R5 + ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 + ${If} "$R5" == "$INSTDIR\${FileMainEXE}" + ApplicationID::UninstallPinnedItem "$R7\TaskBar\$R8" + Pop $R5 + ${EndIf} + ${EndIf} + ClearErrors + FindNext $R6 $R8 + ${If} ${Errors} + ${ExitDo} + ${EndIf} + ${Loop} + FindClose $R6 + ${EndIf} + + ${If} ${FileExists} "$R7\StartMenu" + ; Delete Start Menu pinned shortcuts for the application's main exe + FindFirst $R6 $R8 "$R7\StartMenu\*.lnk" + ${Do} + ${If} ${FileExists} "$R7\StartMenu\$R8" + ShellLink::GetShortCutTarget "$R7\StartMenu\$R8" + Pop $R5 + ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 + ${If} "$R5" == "$INSTDIR\${FileMainEXE}" + ApplicationID::UninstallPinnedItem "$R7\StartMenu\$R8" + Pop $R5 + ${EndIf} + ${EndIf} + ClearErrors + FindNext $R6 $R8 + ${If} ${Errors} + ${ExitDo} + ${EndIf} + ${Loop} + FindClose $R6 + ${EndIf} + ${EndIf} + + ; Don't call ApplicationID::UninstallPinnedItem since pinned items for + ; this application were removed above and removing them below will remove + ; the association of side by side installations. ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" $R9 - IfFileExists $R9 +1 end_DeleteShortcuts + ${If} ${FileExists} "$R9" + ; Delete Start Menu shortcuts for this application + StrCpy $R4 -1 + ${Do} + IntOp $R4 $R4 + 1 ; Increment the counter + ClearErrors + ReadINIStr $R8 "$R9" "STARTMENU" "Shortcut$R4" + ${If} ${Errors} + ${ExitDo} + ${EndIf} - ; Delete Start Menu shortcuts for this application - StrCpy $R4 -1 + ${If} ${FileExists} "$SMPROGRAMS\$R8" + ShellLink::GetShortCutTarget "$SMPROGRAMS\$R8" + Pop $R5 + ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 + ${If} "$INSTDIR\${FileMainEXE}" == "$R5" + Delete "$SMPROGRAMS\$R8" + ${EndIf} + ${EndIf} + ${Loop} - IntOp $R4 $R4 + 1 ; Increment the counter - ClearErrors - ReadINIStr $R8 "$R9" "STARTMENU" "Shortcut$R4" - IfErrors +9 +1 - IfFileExists "$STARTMENU\$R8" +1 -4 - ShellLink::GetShortCutTarget "$STARTMENU\$R8" - Pop $R5 - StrCmp "$INSTDIR\${FileMainEXE}" "$R5" +1 -7 - ApplicationID::UninstallPinnedItem "$STARTMENU\$R8" - Pop $R5 - Delete "$STARTMENU\$R8" - GoTo -11 + ; Delete Quick Launch shortcuts for this application + StrCpy $R4 -1 + ${Do} + IntOp $R4 $R4 + 1 ; Increment the counter + ClearErrors + ReadINIStr $R8 "$R9" "QUICKLAUNCH" "Shortcut$R4" + ${If} ${Errors} + ${ExitDo} + ${EndIf} - ; Delete Quick Launch shortcuts for this application - StrCpy $R4 -1 + ${If} ${FileExists} "$QUICKLAUNCH\$R8" + ShellLink::GetShortCutTarget "$QUICKLAUNCH\$R8" + Pop $R5 + ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 + ${If} "$INSTDIR\${FileMainEXE}" == "$R5" + Delete "$QUICKLAUNCH\$R8" + ${EndIf} + ${EndIf} + ${Loop} - IntOp $R4 $R4 + 1 ; Increment the counter - ClearErrors - ReadINIStr $R8 "$R9" "QUICKLAUNCH" "Shortcut$R4" - IfErrors +9 +1 - IfFileExists "$QUICKLAUNCH\$R8" +1 -4 - ShellLink::GetShortCutTarget "$QUICKLAUNCH\$R8" - Pop $R5 - StrCmp "$INSTDIR\${FileMainEXE}" "$R5" +1 -7 - ApplicationID::UninstallPinnedItem "$QUICKLAUNCH\$R8" - Pop $R5 - Delete "$QUICKLAUNCH\$R8" - GoTo -11 + ; Delete Desktop shortcuts for this application + StrCpy $R4 -1 + ${Do} + IntOp $R4 $R4 + 1 ; Increment the counter + ClearErrors + ReadINIStr $R8 "$R9" "DESKTOP" "Shortcut$R4" + ${If} ${Errors} + ${ExitDo} + ${EndIf} - ; Delete Desktop shortcuts for this application - StrCpy $R4 -1 + ${If} ${FileExists} "$DESKTOP\$R8" + ShellLink::GetShortCutTarget "$DESKTOP\$R8" + Pop $R5 + ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 + ${If} "$INSTDIR\${FileMainEXE}" == "$R5" + Delete "$DESKTOP\$R8" + ${EndIf} + ${EndIf} + ${Loop} - IntOp $R4 $R4 + 1 ; Increment the counter - ClearErrors - ReadINIStr $R8 "$R9" "DESKTOP" "Shortcut$R4" - IfErrors +9 +1 - IfFileExists "$DESKTOP\$R8" +1 -4 - ShellLink::GetShortCutTarget "$DESKTOP\$R8" - Pop $R5 - StrCmp "$INSTDIR\${FileMainEXE}" "$R5" +1 -7 - ApplicationID::UninstallPinnedItem "$DESKTOP\$R8" - Pop $R5 - Delete "$DESKTOP\$R8" - GoTo -11 + ${${_MOZFUNC_UN}GetLongPath} "$SMPROGRAMS" $R6 - ${${_MOZFUNC_UN}GetLongPath} "$SMPROGRAMS" $R6 + ; Delete Start Menu Programs shortcuts for this application + ClearErrors + ReadINIStr $R7 "$R9" "SMPROGRAMS" "RelativePathToDir" + ${${_MOZFUNC_UN}GetLongPath} "$R6\$R7" $R7 + ${Unless} "$R7" == "" + StrCpy $R4 -1 + ${Do} + IntOp $R4 $R4 + 1 ; Increment the counter + ClearErrors + ReadINIStr $R8 "$R9" "SMPROGRAMS" "Shortcut$R4" + ${If} ${Errors} + ${ExitDo} + ${EndIf} - ; Delete Start Menu Programs shortcuts for this application - ClearErrors - ReadINIStr $R7 "$R9" "SMPROGRAMS" "RelativePathToDir" - ${${_MOZFUNC_UN}GetLongPath} "$R6\$R7" $R7 - StrCmp "$R7" "" end_DeleteShortcuts +1 - StrCpy $R4 -1 + ${If} ${FileExists} "$R7\$R8" + ShellLink::GetShortCutTarget "$R7\$R8" + Pop $R5 + ${${_MOZFUNC_UN}GetLongPath} "$R5" $R5 + ${If} "$INSTDIR\${FileMainEXE}" == "$R5" + Delete "$R7\$R8" + ${EndIf} + ${EndIf} + ${Loop} - IntOp $R4 $R4 + 1 ; Increment the counter - ClearErrors - ReadINIStr $R8 "$R9" "SMPROGRAMS" "Shortcut$R4" - IfErrors +9 +1 - IfFileExists "$R7\$R8" +1 -4 - ShellLink::GetShortCutTarget "$R7\$R8" - Pop $R5 - StrCmp "$INSTDIR\${FileMainEXE}" "$R5" +1 -7 - ApplicationID::UninstallPinnedItem "$R7\$R8" - Pop $R5 - Delete "$R7\$R8" - GoTo -11 + ; Delete Start Menu Programs directories for this application + ${Do} + ClearErrors + ${If} "$R6" == "$R7" + ${ExitDo} + ${EndIf} + RmDir "$R7" + ${If} ${Errors} + ${ExitDo} + ${EndIf} + ${${_MOZFUNC_UN}GetParent} "$R7" $R7 + ${Loop} + ${EndUnless} + ${EndIf} - ; Delete Start Menu Programs directories for this application - start_RemoveSMProgramsDir: - ClearErrors - StrCmp "$R6" "$R7" end_DeleteShortcuts +1 - RmDir "$R7" - IfErrors end_DeleteShortcuts +1 - ${${_MOZFUNC_UN}GetParent} "$R7" $R7 - GoTo start_RemoveSMProgramsDir - - end_DeleteShortcuts: ClearErrors Pop $R4 @@ -4621,6 +4714,7 @@ !insertmacro GetParameters !insertmacro GetParent !insertmacro UnloadUAC + !insertmacro UpdateShortcutAppModelIDs !insertmacro UpdateUninstallLog !verbose push @@ -4753,7 +4847,7 @@ finish: ${UnloadUAC} - System::Call "shell32::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)" + System::Call "shell32::SHChangeNotify(i 0x08000000, i 0, i 0, i 0)" Quit ; Nothing initialized so no need to call OnEndCommon continue: @@ -6039,27 +6133,310 @@ !macroend /** - * Update Start Menu and Taskbar lnk files that point to the current install - * with the current application user model ID. Requires ApplicationID. + * Checks if any pinned TaskBar lnk files point to the executable's path passed + * to the macro. * - * @param _INSTALL_PATH - * The install path of the app + * @param _EXE_PATH + * The executable path + * @return _RESULT + * false if no pinned shotcuts were found for this install location. + * true if pinned shotcuts were found for this install location. + * + * $R5 = stores whether a TaskBar lnk file has been found for the executable + * $R6 = long path returned from GetShortCutTarget and GetLongPath + * $R7 = file name returned from FindFirst and FindNext + * $R8 = find handle for FindFirst and FindNext + * $R9 = _EXE_PATH and _RESULT + */ +!macro IsPinnedToTaskBar + + !ifndef IsPinnedToTaskBar + !insertmacro GetLongPath + + !verbose push + !verbose ${_MOZFUNC_VERBOSE} + !define IsPinnedToTaskBar "!insertmacro IsPinnedToTaskBarCall" + + Function IsPinnedToTaskBar + Exch $R9 + Push $R8 + Push $R7 + Push $R6 + Push $R5 + + StrCpy $R5 "false" + + ${If} ${AtLeastWin7} + ${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar" + FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\TaskBar\*.lnk" + ${Do} + ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar\$R7" + ShellLink::GetShortCutTarget "$QUICKLAUNCH\User Pinned\TaskBar\$R7" + Pop $R6 + ${GetLongPath} "$R6" $R6 + ${If} "$R6" == "$R9" + StrCpy $R5 "true" + ${ExitDo} + ${EndIf} + ${EndIf} + ClearErrors + FindNext $R8 $R7 + ${If} ${Errors} + ${ExitDo} + ${EndIf} + ${Loop} + FindClose $R8 + ${EndIf} + + ClearErrors + + StrCpy $R9 $R5 + + Pop $R5 + Pop $R6 + Pop $R7 + Pop $R8 + Exch $R9 + FunctionEnd + + !verbose pop + !endif +!macroend + +!macro IsPinnedToTaskBarCall _EXE_PATH _RESULT + !verbose push + !verbose ${_MOZFUNC_VERBOSE} + Push "${_EXE_PATH}" + Call IsPinnedToTaskBar + Pop ${_RESULT} + !verbose pop +!macroend + +/** + * Checks if any pinned Start Menu lnk files point to the executable's path + * passed to the macro. + * + * @param _EXE_PATH + * The executable path + * @return _RESULT + * false if no pinned shotcuts were found for this install location. + * true if pinned shotcuts were found for this install location. + * + * $R5 = stores whether a Start Menu lnk file has been found for the executable + * $R6 = long path returned from GetShortCutTarget and GetLongPath + * $R7 = file name returned from FindFirst and FindNext + * $R8 = find handle for FindFirst and FindNext + * $R9 = _EXE_PATH and _RESULT + */ +!macro IsPinnedToStartMenu + + !ifndef IsPinnedToStartMenu + !insertmacro GetLongPath + + !verbose push + !verbose ${_MOZFUNC_VERBOSE} + !define IsPinnedToStartMenu "!insertmacro IsPinnedToStartMenuCall" + + Function IsPinnedToStartMenu + Exch $R9 + Push $R8 + Push $R7 + Push $R6 + Push $R5 + + StrCpy $R5 "false" + + ${If} ${AtLeastWin7} + ${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu" + FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\StartMenu\*.lnk" + ${Do} + ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu\$R7" + ShellLink::GetShortCutTarget "$QUICKLAUNCH\User Pinned\StartMenu\$R7" + Pop $R6 + ${GetLongPath} "$R6" $R6 + ${If} "$R6" == "$R9" + StrCpy $R5 "true" + ${ExitDo} + ${EndIf} + ${EndIf} + ClearErrors + FindNext $R8 $R7 + ${If} ${Errors} + ${ExitDo} + ${EndIf} + ${Loop} + FindClose $R8 + ${EndIf} + + ClearErrors + + StrCpy $R9 $R5 + + Pop $R5 + Pop $R6 + Pop $R7 + Pop $R8 + Exch $R9 + FunctionEnd + + !verbose pop + !endif +!macroend + +!macro IsPinnedToStartMenuCall _EXE_PATH _RESULT + !verbose push + !verbose ${_MOZFUNC_VERBOSE} + Push "${_EXE_PATH}" + Call IsPinnedToStartMenu + Pop ${_RESULT} + !verbose pop +!macroend + +/** + * Gets the number of pinned shortcut lnk files pinned to the Task Bar. + * + * @return _RESULT + * number of pinned shortcut lnk files. + * + * $R7 = file name returned from FindFirst and FindNext + * $R8 = find handle for FindFirst and FindNext + * $R9 = _RESULT + */ +!macro PinnedToTaskBarLnkCount + + !ifndef PinnedToTaskBarLnkCount + !insertmacro GetLongPath + + !verbose push + !verbose ${_MOZFUNC_VERBOSE} + !define PinnedToTaskBarLnkCount "!insertmacro PinnedToTaskBarLnkCountCall" + + Function PinnedToTaskBarLnkCount + Push $R9 + Push $R8 + Push $R7 + + StrCpy $R9 0 + + ${If} ${AtLeastWin7} + ${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar" + FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\TaskBar\*.lnk" + ${Do} + ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\TaskBar\$R7" + IntOp $R9 $R9 + 1 + ${EndIf} + ClearErrors + FindNext $R8 $R7 + ${If} ${Errors} + ${ExitDo} + ${EndIf} + ${Loop} + FindClose $R8 + ${EndIf} + + ClearErrors + + Pop $R7 + Pop $R8 + Exch $R9 + FunctionEnd + + !verbose pop + !endif +!macroend + +!macro PinnedToTaskBarLnkCountCall _RESULT + !verbose push + !verbose ${_MOZFUNC_VERBOSE} + Call PinnedToTaskBarLnkCount + Pop ${_RESULT} + !verbose pop +!macroend + +/** + * Gets the number of pinned shortcut lnk files pinned to the Start Menu. + * + * @return _RESULT + * number of pinned shortcut lnk files. + * + * $R7 = file name returned from FindFirst and FindNext + * $R8 = find handle for FindFirst and FindNext + * $R9 = _RESULT + */ +!macro PinnedToStartMenuLnkCount + + !ifndef PinnedToStartMenuLnkCount + !insertmacro GetLongPath + + !verbose push + !verbose ${_MOZFUNC_VERBOSE} + !define PinnedToStartMenuLnkCount "!insertmacro PinnedToStartMenuLnkCountCall" + + Function PinnedToStartMenuLnkCount + Push $R9 + Push $R8 + Push $R7 + + StrCpy $R9 0 + + ${If} ${AtLeastWin7} + ${AndIf} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu" + FindFirst $R8 $R7 "$QUICKLAUNCH\User Pinned\StartMenu\*.lnk" + ${Do} + ${If} ${FileExists} "$QUICKLAUNCH\User Pinned\StartMenu\$R7" + IntOp $R9 $R9 + 1 + ${EndIf} + ClearErrors + FindNext $R8 $R7 + ${If} ${Errors} + ${ExitDo} + ${EndIf} + ${Loop} + FindClose $R8 + ${EndIf} + + ClearErrors + + Pop $R7 + Pop $R8 + Exch $R9 + FunctionEnd + + !verbose pop + !endif +!macroend + +!macro PinnedToStartMenuLnkCountCall _RESULT + !verbose push + !verbose ${_MOZFUNC_VERBOSE} + Call PinnedToStartMenuLnkCount + Pop ${_RESULT} + !verbose pop +!macroend + +/** + * Update Start Menu / TaskBar lnk files that point to the executable's path + * passed to the macro and all other shortcuts installed by the application with + * the current application user model ID. Requires ApplicationID. + * + * @param _EXE_PATH + * The main application executable path * @param _APP_ID * The application user model ID for the current install * @return _RESULT - * false if no shotcuts were found for this install location. - * true if shotcuts were found for this install location. + * false if no pinned shotcuts were found for this install location. + * true if pinned shotcuts were found for this install location. */ !macro UpdateShortcutAppModelIDs !ifndef UpdateShortcutAppModelIDs + !insertmacro GetLongPath + !verbose push !verbose ${_MOZFUNC_VERBOSE} !define UpdateShortcutAppModelIDs "!insertmacro UpdateShortcutAppModelIDsCall" Function UpdateShortcutAppModelIDs - ClearErrors - ; stack: path, appid Exch $R9 ; stack: $R9, appid | $R9 = path Exch 1 ; stack: appid, $R9 @@ -6071,65 +6448,164 @@ Push $R3 ; stack: $R3, $R5, $R6, $R7, $R8, $R9 Push $R2 - StrCpy $R7 "$QUICKLAUNCH\User Pinned" - StrCpy $R3 "false" - - ClearErrors - - ; $R9 = install path + ; $R9 = main application executable path ; $R8 = appid - ; $R7 = user pinned path - ; $R6 = find handle - ; $R5 = found filename + ; $R7 = path to the application's start menu programs directory + ; $R6 = path to the shortcut log ini file + ; $R5 = shortcut filename ; $R4 = GetShortCutTarget result - ; Taskbar links - FindFirst $R6 $R5 "$R7\TaskBar\*.lnk" - LoopTaskBar: - ${If} ${FileExists} "$R7\TaskBar\$R5" - ShellLink::GetShortCutTarget "$R7\TaskBar\$R5" - Pop $R4 - ${If} "$R4" == "$R9" ; link path == install path - ApplicationID::Set "$R7\TaskBar\$R5" "$R8" - Pop $R4 ; pop Set result off the stack - StrCpy $R3 "true" + StrCpy $R3 "false" + + ${If} ${AtLeastWin7} + ; installed shortcuts + ${${_MOZFUNC_UN}GetLongPath} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" $R6 + ${If} ${FileExists} "$R6" + ; Update the Start Menu shortcuts' App ID for this application + StrCpy $R2 -1 + ${Do} + IntOp $R2 $R2 + 1 ; Increment the counter + ClearErrors + ReadINIStr $R5 "$R6" "STARTMENU" "Shortcut$R2" + ${If} ${Errors} + ${ExitDo} + ${EndIf} + + ${If} ${FileExists} "$SMPROGRAMS\$R5" + ShellLink::GetShortCutTarget "$SMPROGRAMS\$$R5" + Pop $R4 + ${GetLongPath} "$R4" $R4 + ${If} "$R4" == "$R9" ; link path == install path + ApplicationID::Set "$SMPROGRAMS\$R5" "$R8" + Pop $R4 + ${EndIf} + ${EndIf} + ${Loop} + + ; Update the Quick Launch shortcuts' App ID for this application + StrCpy $R2 -1 + ${Do} + IntOp $R2 $R2 + 1 ; Increment the counter + ClearErrors + ReadINIStr $R5 "$R6" "QUICKLAUNCH" "Shortcut$R2" + ${If} ${Errors} + ${ExitDo} + ${EndIf} + + ${If} ${FileExists} "$QUICKLAUNCH\$R5" + ShellLink::GetShortCutTarget "$QUICKLAUNCH\$R5" + Pop $R4 + ${GetLongPath} "$R4" $R4 + ${If} "$R4" == "$R9" ; link path == install path + ApplicationID::Set "$QUICKLAUNCH\$R5" "$R8" + Pop $R4 + ${EndIf} + ${EndIf} + ${Loop} + + ; Update the Desktop shortcuts' App ID for this application + StrCpy $R2 -1 + ${Do} + IntOp $R2 $R2 + 1 ; Increment the counter + ClearErrors + ReadINIStr $R5 "$R6" "DESKTOP" "Shortcut$R2" + ${If} ${Errors} + ${ExitDo} + ${EndIf} + + ${If} ${FileExists} "$DESKTOP\$R5" + ShellLink::GetShortCutTarget "$DESKTOP\$R5" + Pop $R4 + ${GetLongPath} "$R4" $R4 + ${If} "$R4" == "$R9" ; link path == install path + ApplicationID::Set "$DESKTOP\$R5" "$R8" + Pop $R4 + ${EndIf} + ${EndIf} + ${Loop} + + ; Update the Start Menu Programs shortcuts' App ID for this application + ClearErrors + ReadINIStr $R7 "$R6" "SMPROGRAMS" "RelativePathToDir" + ${Unless} ${Errors} + ${${_MOZFUNC_UN}GetLongPath} "$SMPROGRAMS\$R7" $R7 + ${Unless} "$R7" == "" + StrCpy $R2 -1 + ${Do} + IntOp $R2 $R2 + 1 ; Increment the counter + ClearErrors + ReadINIStr $R5 "$R6" "SMPROGRAMS" "Shortcut$R2" + ${If} ${Errors} + ${ExitDo} + ${EndIf} + + ${If} ${FileExists} "$R7\$R5" + ShellLink::GetShortCutTarget "$R7\$R5" + Pop $R4 + ${GetLongPath} "$R4" $R4 + ${If} "$R4" == "$R9" ; link path == install path + ApplicationID::Set "$R7\$R5" "$R8" + Pop $R4 + ${EndIf} + ${EndIf} + ${Loop} + ${EndUnless} + ${EndUnless} ${EndIf} + + StrCpy $R7 "$QUICKLAUNCH\User Pinned" + StrCpy $R3 "false" + + ; $R9 = main application executable path + ; $R8 = appid + ; $R7 = user pinned path + ; $R6 = find handle + ; $R5 = found filename + ; $R4 = GetShortCutTarget result + + ; TaskBar links + FindFirst $R6 $R5 "$R7\TaskBar\*.lnk" + ${Do} + ${If} ${FileExists} "$R7\TaskBar\$R5" + ShellLink::GetShortCutTarget "$R7\TaskBar\$R5" + Pop $R4 + ${If} "$R4" == "$R9" ; link path == install path + ApplicationID::Set "$R7\TaskBar\$R5" "$R8" + Pop $R4 ; pop Set result off the stack + StrCpy $R3 "true" + ${EndIf} + ${EndIf} + ClearErrors + FindNext $R6 $R5 + ${If} ${Errors} + ${ExitDo} + ${EndIf} + ${Loop} + FindClose $R6 + + ; Start menu links + FindFirst $R6 $R5 "$R7\StartMenu\*.lnk" + ${Do} + ${If} ${FileExists} "$R7\StartMenu\$R5" + ShellLink::GetShortCutTarget "$R7\StartMenu\$R5" + Pop $R4 + ${If} "$R4" == "$R9" ; link path == install path + ApplicationID::Set "$R7\StartMenu\$R5" "$R8" + Pop $R4 ; pop Set result off the stack + StrCpy $R3 "true" + ${EndIf} + ${EndIf} + ClearErrors + FindNext $R6 $R5 + ${If} ${Errors} + ${ExitDo} + ${EndIf} + ${Loop} + FindClose $R6 ${EndIf} - ClearErrors - FindNext $R6 $R5 - ${Unless} ${Errors} - Goto LoopTaskBar - ${EndUnless} - FindClose $R6 ClearErrors - ; Start menu links - FindFirst $R6 $R5 "$R7\StartMenu\*.lnk" - LoopStartMenu: - ${If} ${FileExists} "$R7\StartMenu\$R5" - ShellLink::GetShortCutTarget "$R7\StartMenu\$R5" - Pop $R4 - ${If} "$R4" == "$R9" ; link path == install path - ApplicationID::Set "$R7\StartMenu\$R5" "$R8" - Pop $R4 ; pop Set result off the stack - StrCpy $R3 "true" - ${EndIf} - ${EndIf} - ClearErrors - FindNext $R6 $R5 - ${Unless} ${Errors} - Goto LoopStartMenu - ${EndUnless} - FindClose $R6 - - ; installed shortcuts - ${GetSMProgramsDirRelPath} $R2 - ${If} "$R2" != "" - ApplicationID::Set "$SMPROGRAMS\$R2\${BrandFullName}.lnk" "${AppUserModelID}" - ApplicationID::Set "$SMPROGRAMS\$R2\${BrandFullName} ($(SAFE_MODE)).lnk" "${AppUserModelID}" - ${EndIf} - StrCpy $R9 $R3 Pop $R2 @@ -6147,11 +6623,11 @@ !endif !macroend -!macro UpdateShortcutAppModelIDsCall _INSTALL_PATH _APP_ID _RESULT +!macro UpdateShortcutAppModelIDsCall _EXE_PATH _APP_ID _RESULT !verbose push !verbose ${_MOZFUNC_VERBOSE} Push "${_APP_ID}" - Push "${_INSTALL_PATH}" + Push "${_EXE_PATH}" Call UpdateShortcutAppModelIDs Pop ${_RESULT} !verbose pop diff --git a/toolkit/mozapps/installer/windows/nsis/makensis.mk b/toolkit/mozapps/installer/windows/nsis/makensis.mk index 37c8bf108e8e..57a3ce58fcf3 100644 --- a/toolkit/mozapps/installer/windows/nsis/makensis.mk +++ b/toolkit/mozapps/installer/windows/nsis/makensis.mk @@ -57,6 +57,7 @@ CUSTOM_NSIS_PLUGINS = \ AccessControl.dll \ AppAssocReg.dll \ ApplicationID.dll \ + InvokeShellVerb.dll \ ShellLink.dll \ UAC.dll \ $(NULL)