author | Bogdan Tara <btara@mozilla.com> |
Tue, 23 Oct 2018 19:18:10 +0300 | |
changeset 490945 | 1944104ccd9dfe6f8db7a698a5847240274611ee |
parent 490944 | a4f2759633f74ba30a73a35bc5e32fbaf0f7c0a0 |
child 490946 | 72cca5ce21f435e245a20dc518f1ffb6f72c748c |
push id | 247 |
push user | fmarier@mozilla.com |
push date | Sat, 27 Oct 2018 01:06:44 +0000 |
bugs | 1453613 |
milestone | 65.0a1 |
backs out | 77fabbff45e0d2ede394a205b7e787360c7ad9fc 1df447ff4c775115522c4c70366db19e59b0e12c |
--- a/browser/installer/windows/nsis/defines.nsi.in +++ b/browser/installer/windows/nsis/defines.nsi.in @@ -134,14 +134,8 @@ VIAddVersionKey "ProductVersion" "${App !define PROFILE_CLEANUP_LABEL_TOP_DU 39u !define NOW_INSTALLING_TOP_DU 70u !define INSTALL_BLURB_TOP_DU 137u !define INSTALL_FOOTER_TOP_DU -48u !define INSTALL_FOOTER_WIDTH_DU 250u !define PROGRESS_BAR_TOP_DU 112u !define APPNAME_BMP_EDGE_DU 19u !define APPNAME_BMP_TOP_DU 12u - -# Constants for parts of the telemetry submission URL -!define TELEMETRY_BASE_URL https://incoming.telemetry.mozilla.org/submit -!define TELEMETRY_NAMESPACE firefox-installer -!define TELEMETRY_INSTALL_PING_VERSION 1 -!define TELEMETRY_INSTALL_PING_DOCTYPE install
--- a/browser/installer/windows/nsis/installer.nsi +++ b/browser/installer/windows/nsis/installer.nsi @@ -1,17 +1,16 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # Required Plugins: # AppAssocReg http://nsis.sourceforge.net/Application_Association_Registration_plug-in # ApplicationID http://nsis.sourceforge.net/ApplicationID_plug-in # CityHash http://dxr.mozilla.org/mozilla-central/source/other-licenses/nsis/Contrib/CityHash -# nsJSON http://nsis.sourceforge.net/NsJSON_plug-in # ShellLink http://nsis.sourceforge.net/ShellLink_plug-in # UAC http://nsis.sourceforge.net/UAC_plug-in # ServicesHelper Mozilla specific plugin that is located in /other-licenses/nsis ; Set verbosity to 3 (e.g. no script) to lessen the noise in the build logs !verbose 3 ; 7-Zip provides better compression than the lzma from NSIS so we add the files @@ -35,28 +34,16 @@ Var AddTaskbarSC Var AddQuickLaunchSC Var AddDesktopSC Var InstallMaintenanceService Var InstallOptionalExtensions Var ExtensionRecommender Var PageName Var PreventRebootRequired -; Telemetry ping fields -Var SetAsDefault -Var HadOldInstall -Var DefaultInstDir -Var IntroPhaseStart -Var OptionsPhaseStart -Var InstallPhaseStart -Var FinishPhaseStart -Var FinishPhaseEnd -Var InstallResult -Var LaunchedNewApp - ; By defining NO_STARTMENU_DIR an installer that doesn't provide an option for ; an application's Start Menu PROGRAMS directory and doesn't define the ; StartMenuDir variable can use the common InstallOnInitCommon macro. !define NO_STARTMENU_DIR ; Attempt to elevate Standard Users in addition to users that ; are a member of the Administrators group. !define NONADMIN_ELEVATE @@ -92,17 +79,16 @@ VIAddVersionKey "OriginalFilename" "setu !insertmacro _LoggingCommon !insertmacro AddDisabledDDEHandlerValues !insertmacro ChangeMUIHeaderImage !insertmacro CheckForFilesInUse !insertmacro CleanUpdateDirectories !insertmacro CopyFilesFromDir !insertmacro CreateRegKey -!insertmacro GetFirstInstallPath !insertmacro GetLongPath !insertmacro GetPathFromString !insertmacro GetParent !insertmacro InitHashAppModelId !insertmacro IsHandlerForInstallDir !insertmacro IsPinnedToTaskBar !insertmacro IsUserAdmin !insertmacro LogDesktopShortcut @@ -197,30 +183,26 @@ Page custom preSummary leaveSummary !insertmacro MUI_PAGE_INSTFILES ; Finish Page !define MUI_FINISHPAGE_TITLE_3LINES !define MUI_FINISHPAGE_RUN !define MUI_FINISHPAGE_RUN_FUNCTION LaunchApp !define MUI_FINISHPAGE_RUN_TEXT $(LAUNCH_TEXT) !define MUI_PAGE_CUSTOMFUNCTION_PRE preFinish -!define MUI_PAGE_CUSTOMFUNCTION_LEAVE postFinish !insertmacro MUI_PAGE_FINISH ; Use the default dialog for IDD_VERIFY for a simple Banner ChangeUI IDD_VERIFY "${NSISDIR}\Contrib\UIs\default.exe" ################################################################################ # Install Sections ; Cleanup operations to perform at the start of the installation. Section "-InstallStartCleanup" - System::Call "kernel32::GetTickCount()l .s" - Pop $InstallPhaseStart - SetDetailsPrint both DetailPrint $(STATUS_CLEANUP) SetDetailsPrint none SetOutPath "$INSTDIR" ${StartInstallLog} "${BrandFullName}" "${AB_CD}" "${AppVersion}" "${GREVersion}" StrCpy $R9 "true" @@ -670,17 +652,17 @@ Section "-InstallEndCleanup" SetDetailsPrint both DetailPrint "$(STATUS_CLEANUP)" SetDetailsPrint none ${Unless} ${Silent} ClearErrors ${MUI_INSTALLOPTIONS_READ} $0 "summary.ini" "Field 4" "State" ${If} "$0" == "1" - StrCpy $SetAsDefault true + ; NB: this code is duplicated in stub.nsi. Please keep in sync. ; For data migration in the app, we want to know what the default browser ; value was before we changed it. To do so, we read it here and store it ; in our own registry key. StrCpy $0 "" AppAssocReg::QueryCurrentDefault "http" "protocol" "effective" Pop $1 ; If the method hasn't failed, $1 will contain the progid. Check: ${If} "$1" != "method failed" @@ -705,17 +687,16 @@ Section "-InstallEndCleanup" ${GetOptions} "$0" "/UAC:" $0 ${If} ${Errors} Call SetAsDefaultAppUserHKCU ${Else} GetFunctionAddress $0 SetAsDefaultAppUserHKCU UAC::ExecCodeSegment $0 ${EndIf} ${ElseIfNot} ${Errors} - StrCpy $SetAsDefault false ${LogHeader} "Writing default-browser opt-out" ClearErrors WriteRegStr HKCU "Software\Mozilla\Firefox" "DefaultBrowserOptOut" "True" ${If} ${Errors} ${LogMsg} "Error writing default-browser opt-out" ${EndIf} ${EndIf} ${EndUnless} @@ -764,24 +745,16 @@ Section "-InstallEndCleanup" FileWrite $0 "Will be deleted on restart" Rename /REBOOTOK "$INSTDIR\${FileMainEXE}.moz-upgrade" "$INSTDIR\${FileMainEXE}" FileClose $0 Delete "$INSTDIR\${FileMainEXE}" Rename "$INSTDIR\helper.exe" "$INSTDIR\${FileMainEXE}" ${EndUnless} ${EndIf} ${EndIf} - - StrCpy $InstallResult "success" - - ; When we're using the GUI, .onGUIEnd sends the ping, but of course that isn't - ; invoked when we're running silently. - ${If} ${Silent} - Call SendPing - ${EndIf} SectionEnd ################################################################################ # Install Abort Survey Functions Function CustomAbort ${If} "${AB_CD}" == "en-US" ${AndIf} "$PageName" != "" @@ -920,191 +893,25 @@ Function LaunchApp ${GetParameters} $0 ${GetOptions} "$0" "/UAC:" $1 ${If} ${Errors} ${ExecAndWaitForInputIdle} "$\"$INSTDIR\${FileMainEXE}$\"" ${Else} GetFunctionAddress $0 LaunchAppFromElevatedProcess UAC::ExecCodeSegment $0 ${EndIf} - - StrCpy $LaunchedNewApp true FunctionEnd Function LaunchAppFromElevatedProcess ; Set our current working directory to the application's install directory ; otherwise the 7-Zip temp directory will be in use and won't be deleted. SetOutPath "$INSTDIR" ${ExecAndWaitForInputIdle} "$\"$INSTDIR\${FileMainEXE}$\"" FunctionEnd -Function SendPing - ${GetParameters} $0 - ${GetOptions} $0 "/LaunchedFromStub" $0 - ${IfNot} ${Errors} - Return - ${EndIf} - - ; Create a GUID to use as the unique document ID. - System::Call "rpcrt4::UuidCreate(g . r0)i" - ; StringFromGUID2 (which is what System::Call uses internally to stringify - ; GUIDs) includes braces in its output, and we don't want those. - StrCpy $0 $0 -1 1 - - ; Configure the HTTP request for the ping - nsJSON::Set /tree ping /value "{}" - nsJSON::Set /tree ping "Url" /value \ - '"${TELEMETRY_BASE_URL}/${TELEMETRY_NAMESPACE}/${TELEMETRY_INSTALL_PING_DOCTYPE}/${TELEMETRY_INSTALL_PING_VERSION}/$0"' - nsJSON::Set /tree ping "Verb" /value '"POST"' - nsJSON::Set /tree ping "DataType" /value '"JSON"' - nsJSON::Set /tree ping "AccessType" /value '"PreConfig"' - - ; Fill in the ping payload - nsJSON::Set /tree ping "Data" /value "{}" - nsJSON::Set /tree ping "Data" "installer_type" /value '"full"' - nsJSON::Set /tree ping "Data" "installer_version" /value '"${AppVersion}"' - nsJSON::Set /tree ping "Data" "build_channel" /value '"${Channel}"' - nsJSON::Set /tree ping "Data" "update_channel" /value '"${UpdateChannel}"' - nsJSON::Set /tree ping "Data" "locale" /value '"${AB_CD}"' - - ReadINIStr $0 "$INSTDIR\application.ini" "App" "Version" - nsJSON::Set /tree ping "Data" "version" /value '"$0"' - ReadINIStr $0 "$INSTDIR\application.ini" "App" "BuildID" - nsJSON::Set /tree ping "Data" "build_id" /value '"$0"' - - ${GetParameters} $0 - ${GetOptions} $0 "/LaunchedFromMSI" $0 - ${IfNot} ${Errors} - nsJSON::Set /tree ping "Data" "from_msi" /value true - ${EndIf} - - !ifdef HAVE_64BIT_BUILD - nsJSON::Set /tree ping "Data" "64bit_build" /value true - !else - nsJSON::Set /tree ping "Data" "64bit_build" /value false - !endif - - ${If} ${RunningX64} - nsJSON::Set /tree ping "Data" "64bit_os" /value true - ${Else} - nsJSON::Set /tree ping "Data" "64bit_os" /value false - ${EndIf} - - ; Though these values are sometimes incorrect due to bug 444664 it happens - ; so rarely it isn't worth working around it by reading the registry values. - ${WinVerGetMajor} $0 - ${WinVerGetMinor} $1 - ${WinVerGetBuild} $2 - nsJSON::Set /tree ping "Data" "os_version" /value '"$0.$1.$2"' - ${If} ${IsServerOS} - nsJSON::Set /tree ping "Data" "server_os" /value true - ${Else} - nsJSON::Set /tree ping "Data" "server_os" /value false - ${EndIf} - - ClearErrors - WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" \ - "Write Test" - ${If} ${Errors} - nsJSON::Set /tree ping "Data" "admin_user" /value false - ${Else} - DeleteRegValue HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" - nsJSON::Set /tree ping "Data" "admin_user" /value true - ${EndIf} - - ${If} $DefaultInstDir == $INSTDIR - nsJSON::Set /tree ping "Data" "default_path" /value true - ${Else} - nsJSON::Set /tree ping "Data" "default_path" /value false - ${EndIf} - - nsJSON::Set /tree ping "Data" "set_default" /value "$SetAsDefault" - - nsJSON::Set /tree ping "Data" "new_default" /value false - nsJSON::Set /tree ping "Data" "old_default" /value false - - AppAssocReg::QueryCurrentDefault "http" "protocol" "effective" - Pop $0 - ReadRegStr $0 HKCR "$0\shell\open\command" "" - ${If} $0 != "" - ${GetPathFromString} "$0" $0 - ${GetParent} "$0" $1 - ${GetLongPath} "$1" $1 - ${If} $1 == $INSTDIR - nsJSON::Set /tree ping "Data" "new_default" /value true - ${Else} - StrCpy $0 "$0" "" -11 # 11 == length of "firefox.exe" - ${If} "$0" == "${FileMainEXE}" - nsJSON::Set /tree ping "Data" "old_default" /value true - ${EndIf} - ${EndIf} - ${EndIf} - - nsJSON::Set /tree ping "Data" "had_old_install" /value "$HadOldInstall" - - ${If} ${Silent} - ; In silent mode, only the install phase is executed, and the GUI events - ; that initialize most of the phase times are never called; only - ; $InstallPhaseStart and $FinishPhaseStart have usable values. - ${GetSecondsElapsed} $InstallPhaseStart $FinishPhaseStart $0 - - nsJSON::Set /tree ping "Data" "intro_time" /value 0 - nsJSON::Set /tree ping "Data" "options_time" /value 0 - nsJSON::Set /tree ping "Data" "install_time" /value "$0" - nsJSON::Set /tree ping "Data" "finish_time" /value 0 - ${Else} - ; In GUI mode, all we can be certain of is that the intro phase has started; - ; the user could have canceled at any time and phases after that won't - ; have run at all. So we have to be prepared for anything after - ; $IntroPhaseStart to be uninitialized. For anything that isn't filled in - ; yet we'll use the current tick count. That means that any phases that - ; weren't entered at all will get 0 for their times because the start and - ; end tick counts will be the same. - System::Call "kernel32::GetTickCount()l .s" - Pop $0 - - ${If} $OptionsPhaseStart == 0 - StrCpy $OptionsPhaseStart $0 - ${EndIf} - ${GetSecondsElapsed} $IntroPhaseStart $OptionsPhaseStart $1 - nsJSON::Set /tree ping "Data" "intro_time" /value "$1" - - ${If} $InstallPhaseStart == 0 - StrCpy $InstallPhaseStart $0 - ${EndIf} - ${GetSecondsElapsed} $OptionsPhaseStart $InstallPhaseStart $1 - nsJSON::Set /tree ping "Data" "options_time" /value "$1" - - ${If} $FinishPhaseStart == 0 - StrCpy $FinishPhaseStart $0 - ${EndIf} - ${GetSecondsElapsed} $InstallPhaseStart $FinishPhaseStart $1 - nsJSON::Set /tree ping "Data" "install_time" /value "$1" - - ${If} $FinishPhaseEnd == 0 - StrCpy $FinishPhaseEnd $0 - ${EndIf} - ${GetSecondsElapsed} $FinishPhaseStart $FinishPhaseEnd $1 - nsJSON::Set /tree ping "Data" "finish_time" /value "$1" - ${EndIf} - - nsJSON::Set /tree ping "Data" "new_launched" /value "$LaunchedNewApp" - - nsJSON::Set /tree ping "Data" "succeeded" /value false - ${If} $InstallResult == "cancel" - nsJSON::Set /tree ping "Data" "user_cancelled" /value true - ${ElseIf} $InstallResult == "success" - nsJSON::Set /tree ping "Data" "succeeded" /value true - ${EndIf} - - ; Send the ping request. This call will block until a response is received, - ; but we shouldn't have any windows still open, so we won't jank anything. - nsJSON::Set /http ping -FunctionEnd - ################################################################################ # Language !insertmacro MOZ_MUI_LANGUAGE 'baseLocale' !verbose push !verbose 3 !include "overrideLocale.nsh" !include "customLocale.nsh" @@ -1121,25 +928,19 @@ BrandingText " " # Page pre, show, and leave functions Function preWelcome StrCpy $PageName "Welcome" ${If} ${FileExists} "$EXEDIR\core\distribution\modern-wizard.bmp" Delete "$PLUGINSDIR\modern-wizard.bmp" CopyFiles /SILENT "$EXEDIR\core\distribution\modern-wizard.bmp" "$PLUGINSDIR\modern-wizard.bmp" ${EndIf} - - System::Call "kernel32::GetTickCount()l .s" - Pop $IntroPhaseStart FunctionEnd Function preOptions - System::Call "kernel32::GetTickCount()l .s" - Pop $OptionsPhaseStart - StrCpy $PageName "Options" ${If} ${FileExists} "$EXEDIR\core\distribution\modern-header.bmp" ${AndIf} $hHeaderBitmap == "" Delete "$PLUGINSDIR\modern-header.bmp" CopyFiles /SILENT "$EXEDIR\core\distribution\modern-header.bmp" "$PLUGINSDIR\modern-header.bmp" ${ChangeMUIHeaderImage} "$PLUGINSDIR\modern-header.bmp" ${EndIf} !insertmacro MUI_HEADER_TEXT "$(OPTIONS_PAGE_TITLE)" "$(OPTIONS_PAGE_SUBTITLE)" @@ -1163,18 +964,16 @@ Function leaveOptions ${If} $InstallType == ${INSTALLTYPE_BASIC} Call CheckExistingInstall ${EndIf} FunctionEnd Function preDirectory StrCpy $PageName "Directory" ${PreDirectoryCommon} - - StrCpy $DefaultInstDir $INSTDIR FunctionEnd Function leaveDirectory ${If} $InstallType == ${INSTALLTYPE_BASIC} Call CheckExistingInstall ${EndIf} ${LeaveDirectoryCommon} "$(WARN_DISK_SPACE)" "$(WARN_WRITE_ACCESS)" FunctionEnd @@ -1478,49 +1277,29 @@ Function leaveSummary ${If} ${Errors} ${ManualCloseAppPrompt} "${WindowClass}" "$(WARN_MANUALLY_CLOSE_APP_INSTALL)" ${EndIf} FunctionEnd ; When we add an optional action to the finish page the cancel button is ; enabled. This disables it and leaves the finish button as the only choice. Function preFinish - System::Call "kernel32::GetTickCount()l .s" - Pop $FinishPhaseStart - StrCpy $PageName "" ${EndInstallLog} "${BrandFullName}" !insertmacro MUI_INSTALLOPTIONS_WRITE "ioSpecial.ini" "settings" "cancelenabled" "0" FunctionEnd -Function postFinish - System::Call "kernel32::GetTickCount()l .s" - Pop $FinishPhaseEnd -FunctionEnd - ################################################################################ # Initialization Functions Function .onInit ; Remove the current exe directory from the search order. ; This only effects LoadLibrary calls and not implicitly loaded DLLs. System::Call 'kernel32::SetDllDirectoryW(w "")' - ; Initialize the variables used for telemetry - StrCpy $SetAsDefault true - StrCpy $HadOldInstall false - StrCpy $DefaultInstDir $INSTDIR - StrCpy $IntroPhaseStart 0 - StrCpy $OptionsPhaseStart 0 - StrCpy $InstallPhaseStart 0 - StrCpy $FinishPhaseStart 0 - StrCpy $FinishPhaseEnd 0 - StrCpy $InstallResult "cancel" - StrCpy $LaunchedNewApp false - StrCpy $PageName "" StrCpy $LANGUAGE 0 ${SetBrandNameVars} "$EXEDIR\core\distribution\setup.ini" ; Don't install on systems that don't support SSE2. The parameter value of ; 10 is for PF_XMMI64_INSTRUCTIONS_AVAILABLE which will check whether the ; SSE2 instruction set is available. Result returned in $R7. System::Call "kernel32::IsProcessorFeaturePresent(i 10)i .R7" @@ -1548,30 +1327,16 @@ Function .onInit ${Unless} ${RunningX64} MessageBox MB_OKCANCEL|MB_ICONSTOP "$(WARN_MIN_SUPPORTED_OSVER_MSG)" IDCANCEL +2 ExecShell "open" "${URLSystemRequirements}" Quit ${EndUnless} SetRegView 64 !endif - SetShellVarContext all - ${GetFirstInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $0 - ${If} "$0" == "false" - SetShellVarContext current - ${GetFirstInstallPath} "Software\Mozilla\${BrandFullNameInternal}" $0 - ${If} "$0" == "false" - StrCpy $HadOldInstall false - ${Else} - StrCpy $HadOldInstall true - ${EndIf} - ${Else} - StrCpy $HadOldInstall true - ${EndIf} - ${InstallOnInitCommon} "$(WARN_MIN_SUPPORTED_OSVER_CPU_MSG)" !insertmacro InitInstallOptionsFile "options.ini" !insertmacro InitInstallOptionsFile "shortcuts.ini" !insertmacro InitInstallOptionsFile "components.ini" !insertmacro InitInstallOptionsFile "extensions.ini" !insertmacro InitInstallOptionsFile "summary.ini" @@ -1751,10 +1516,9 @@ Function .onInit ; Initialize $hHeaderBitmap to prevent redundant changing of the bitmap if ; the user clicks the back button StrCpy $hHeaderBitmap "" FunctionEnd Function .onGUIEnd ${OnEndCommon} - Call SendPing FunctionEnd
--- a/browser/installer/windows/nsis/stub.nsi +++ b/browser/installer/windows/nsis/stub.nsi @@ -1213,17 +1213,17 @@ Function LaunchFullInstaller ; since it being present will require an OS restart for the full ; installer. Delete "$INSTDIR\${FileMainEXE}.moz-upgrade" Delete "$INSTDIR\${FileMainEXE}.moz-delete" System::Call "kernel32::GetTickCount()l .s" Pop $EndPreInstallPhaseTickCount - Exec "$\"$PLUGINSDIR\download.exe$\" /LaunchedFromStub /INI=$PLUGINSDIR\${CONFIG_INI}" + Exec "$\"$PLUGINSDIR\download.exe$\" /INI=$PLUGINSDIR\${CONFIG_INI}" ${NSD_CreateTimer} CheckInstall ${InstallIntervalMS} FunctionEnd Function SendPing ${NSD_KillTimer} NextBlurb ${NSD_KillTimer} ClearBlurb HideWindow
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..36e5263d92f712a3047aa379f32c4d9063da9e8a GIT binary patch literal 18944 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 b``9i#k^9qJs%Pn2s!Nmp_nPZ}_2+*A-SuN2
--- a/toolkit/mozapps/installer/windows/nsis/common.nsh +++ b/toolkit/mozapps/installer/windows/nsis/common.nsh @@ -1707,134 +1707,16 @@ !insertmacro GetSingleInstallPath !undef _MOZFUNC_UN !define _MOZFUNC_UN !verbose pop !endif !macroend -/** - * Find the first existing installation for the application. - * This is similar to GetSingleInstallPath, except that it always returns the - * first path it finds, instead of an error when more than one path exists. - * - * The shell context and the registry view should already have been set. - * - * @param _KEY - * The registry subkey (typically Software\Mozilla\App Name). - * @return _RESULT - * path to the install directory of the first location found, or - * the string "false" if no existing installation was found. - * - * $R5 = counter for the loop's EnumRegKey - * $R6 = return value from EnumRegKey - * $R7 = return value from ReadRegStr - * $R8 = storage for _KEY - * $R9 = _KEY and _RESULT - */ -!macro GetFirstInstallPath - !ifndef ${_MOZFUNC_UN}GetFirstInstallPath - !define _MOZFUNC_UN_TMP ${_MOZFUNC_UN} - !insertmacro ${_MOZFUNC_UN_TMP}GetLongPath - !insertmacro ${_MOZFUNC_UN_TMP}GetParent - !insertmacro ${_MOZFUNC_UN_TMP}RemoveQuotesFromPath - !undef _MOZFUNC_UN - !define _MOZFUNC_UN ${_MOZFUNC_UN_TMP} - !undef _MOZFUNC_UN_TMP - - !verbose push - !verbose ${_MOZFUNC_VERBOSE} - !define ${_MOZFUNC_UN}GetFirstInstallPath "!insertmacro ${_MOZFUNC_UN}__GetFirstInstallPathCall" - - Function ${_MOZFUNC_UN}__GetFirstInstallPath - Exch $R9 - Push $R8 - Push $R7 - Push $R6 - Push $R5 - - StrCpy $R8 $R9 - StrCpy $R9 "false" - StrCpy $R5 0 - - ${Do} - ClearErrors - EnumRegKey $R6 SHCTX $R8 $R5 - ${If} ${Errors} - ${OrIf} $R6 == "" - ${Break} - ${EndIf} - - IntOp $R5 $R5 + 1 - - ReadRegStr $R7 SHCTX "$R8\$R6\Main" "PathToExe" - ${If} ${Errors} - ${Continue} - ${EndIf} - - ${${_MOZFUNC_UN}RemoveQuotesFromPath} "$R7" $R7 - GetFullPathName $R7 "$R7" - ${If} ${Errors} - ${Continue} - ${EndIf} - - StrCpy $R9 "$R7" - ${Break} - ${Loop} - - ${If} $R9 != "false" - ${${_MOZFUNC_UN}GetLongPath} "$R9" $R9 - ${${_MOZFUNC_UN}GetParent} "$R9" $R9 - ${EndIf} - - Pop $R5 - Pop $R6 - Pop $R7 - Pop $R8 - Exch $R9 - FunctionEnd - - !verbose pop - !endif -!macroend - -!macro __GetFirstInstallPathCall _KEY _RESULT - !verbose push - !verbose ${_MOZFUNC_VERBOSE} - Push "${_KEY}" - Call __GetFirstInstallPath - Pop ${_RESULT} - !verbose pop -!macroend - -!macro un.__GetFirstInstallPathCall _KEY _RESULT - !verbose push - !verbose ${_MOZFUNC_VERBOSE} - Push "${_KEY}" - Call un.__GetFirstInstallPath - Pop ${_RESULT} - !verbose pop -!macroend - -!macro un.__GetFirstInstallPath - !ifndef un.__GetFirstInstallPath - !verbose push - !verbose ${_MOZFUNC_VERBOSE} - !undef _MOZFUNC_UN - !define _MOZFUNC_UN "un." - - !insertmacro __GetFirstInstallPath - - !undef _MOZFUNC_UN - !define _MOZFUNC_UN - !verbose pop - !endif -!macroend - ################################################################################ # Macros for working with the file system /** * Attempts to delete a file if it exists. This will fail if the file is in use. * * @param _FILE