Bug 398036 - Add file in use install support. r=sspitzer, blocking-firefox3=mconnor

This commit is contained in:
rob_strong@exchangecode.com 2007-11-30 11:02:09 -08:00
Родитель f25524c58f
Коммит 2e2b979b5e
5 изменённых файлов: 503 добавлений и 179 удалений

Просмотреть файл

@ -111,7 +111,9 @@ VIAddVersionKey "FileDescription" "${BrandShortName} Installer"
!insertmacro AddDDEHandlerValues
!insertmacro ChangeMUIHeaderImage
!insertmacro CheckForFilesInUse
!insertmacro CloseApp
!insertmacro CopyFilesFromDir
!insertmacro CreateRegKey
!insertmacro GetPathFromString
!insertmacro GetParent
@ -194,6 +196,7 @@ Page custom preShortcuts leaveShortcuts
; Start Menu Folder Page Configuration
!define MUI_PAGE_CUSTOMFUNCTION_PRE preStartMenu
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE leaveStartMenu
!define MUI_STARTMENUPAGE_NODISABLE
!define MUI_STARTMENUPAGE_REGISTRY_ROOT "HKLM"
!define MUI_STARTMENUPAGE_REGISTRY_KEY "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Main"
@ -207,7 +210,6 @@ Page custom preSummary leaveSummary
!insertmacro MUI_PAGE_INSTFILES
; Finish Page
!define MUI_FINISHPAGE_NOREBOOTSUPPORT
!define MUI_FINISHPAGE_TITLE_3LINES
!define MUI_FINISHPAGE_RUN
!define MUI_FINISHPAGE_RUN_FUNCTION LaunchApp
@ -215,6 +217,9 @@ Page custom preSummary leaveSummary
!define MUI_PAGE_CUSTOMFUNCTION_PRE preFinish
!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
@ -227,55 +232,17 @@ Section "-InstallStartCleanup"
SetOutPath "$INSTDIR"
${StartInstallLog} "${BrandFullName}" "${AB_CD}" "${AppVersion}" "${GREVersion}"
; Try to delete the app's main executable and if we can't delete it try to
; close the app. This allows running an instance that is located in another
; directory and prevents the launching of the app during the installation.
; A copy of the executable is placed in a temporary directory so it can be
; copied back in the case where a specific file is checked / found to be in
; use that would prevent a successful install.
; Create a temporary backup directory.
GetTempFileName $TmpVal "$TEMP"
${DeleteFile} "$TmpVal"
SetOutPath "$TmpVal"
${If} ${FileExists} "$INSTDIR\${FileMainEXE}"
ClearErrors
CopyFiles /SILENT "$INSTDIR\${FileMainEXE}" "$TmpVal\${FileMainEXE}"
Delete "$INSTDIR\${FileMainEXE}"
${If} ${Errors}
ClearErrors
${CloseApp} "true" $(WARN_APP_RUNNING_INSTALL)
; Try to delete it again to prevent launching the app while we are
; installing.
ClearErrors
CopyFiles /SILENT "$INSTDIR\${FileMainEXE}" "$TmpVal\${FileMainEXE}"
Delete "$INSTDIR\${FileMainEXE}"
${If} ${Errors}
ClearErrors
; Try closing the app a second time
${CloseApp} "true" $(WARN_APP_RUNNING_INSTALL)
StrCpy $R1 "${FileMainEXE}"
Call CheckInUse
${EndIf}
${EndIf}
${EndIf}
StrCpy $R1 "freebl3.dll"
Call CheckInUse
StrCpy $R1 "nssckbi.dll"
Call CheckInUse
StrCpy $R1 "nspr4.dll"
Call CheckInUse
StrCpy $R1 "xpicleanup.exe"
Call CheckInUse
SetOutPath "$INSTDIR"
RmDir /r "$TmpVal"
; Delete the app exe to prevent launching the app while we are installing.
ClearErrors
${DeleteFile} "$INSTDIR\${FileMainEXE}"
${If} ${Errors}
; If the user closed the application it can take several seconds for it to
; shut down completely. If the application is being used by another user we
; can rename the file and then delete is when the system is restarted.
Sleep 5000
${DeleteFile} "$INSTDIR\${FileMainEXE}"
ClearErrors
${EndIf}
${If} $InstallType == ${INSTALLTYPE_CUSTOM}
; Custom installs.
@ -299,9 +266,9 @@ Section "-Application" APP_IDX
SetDetailsPrint none
${LogHeader} "Installing Main Files"
StrCpy $R0 "$EXEDIR\nonlocalized"
StrCpy $R1 "$INSTDIR"
Call DoCopyFiles
${CopyFilesFromDir} "$EXEDIR\nonlocalized" "$INSTDIR" \
"$(ERROR_CREATE_DIRECTORY_PREFIX)" \
"$(ERROR_CREATE_DIRECTORY_SUFFIX)"
; Register DLLs
; XXXrstrong - AccessibleMarshal.dll can be used by multiple applications but
@ -336,9 +303,9 @@ Section "-Application" APP_IDX
SetDetailsPrint none
${LogHeader} "Installing Localized Files"
StrCpy $R0 "$EXEDIR\localized"
StrCpy $R1 "$INSTDIR"
Call DoCopyFiles
${CopyFilesFromDir} "$EXEDIR\localized" "$INSTDIR" \
"$(ERROR_CREATE_DIRECTORY_PREFIX)" \
"$(ERROR_CREATE_DIRECTORY_SUFFIX)"
${LogHeader} "Adding Additional Files"
; Check if QuickTime is installed and copy the nsIQTScriptablePlugin.xpt from
@ -505,9 +472,10 @@ Section /o "Developer Tools" DOMI_IDX
${RemoveDir} "$INSTDIR\extensions\inspector@mozilla.org"
ClearErrors
${LogHeader} "Installing Developer Tools"
StrCpy $R0 "$EXEDIR\optional\extensions\inspector@mozilla.org"
StrCpy $R1 "$INSTDIR\extensions\inspector@mozilla.org"
Call DoCopyFiles
${CopyFilesFromDir} "$EXEDIR\optional\extensions\inspector@mozilla.org" \
"$INSTDIR\extensions\inspector@mozilla.org" \
"$(ERROR_CREATE_DIRECTORY_PREFIX)" \
"$(ERROR_CREATE_DIRECTORY_SUFFIX)"
${EndIf}
SectionEnd
@ -518,112 +486,82 @@ Section "-InstallEndCleanup"
SetDetailsPrint none
${LogHeader} "Updating Uninstall Log With Previous Uninstall Log"
${InstallEndCleanupCommon}
; Refresh desktop icons
System::Call "shell32::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)"
${InstallEndCleanupCommon}
; If we have to reboot give SHChangeNotify time to finish the refreshing
; the icons so the OS doesn't display the icons from helper.exe
${If} ${RebootFlag}
Sleep 10000
${LogHeader} "Reboot Required To Finish Installation"
; ${FileMainEXE}.moz-upgrade should never exist but just in case...
${Unless} ${FileExists} "$INSTDIR\${FileMainEXE}.moz-upgrade"
Rename "$INSTDIR\${FileMainEXE}" "$INSTDIR\${FileMainEXE}.moz-upgrade"
${EndUnless}
${If} ${FileExists} "$INSTDIR\${FileMainEXE}"
ClearErrors
Rename "$INSTDIR\${FileMainEXE}" "$INSTDIR\${FileMainEXE}.moz-delete"
${Unless} ${Errors}
Delete /REBOOTOK "$INSTDIR\${FileMainEXE}.moz-delete"
${EndUnless}
${EndUnless}
${Unless} ${FileExists} "$INSTDIR\${FileMainEXE}"
CopyFiles /SILENT "$INSTDIR\uninstall\helper.exe" "$INSTDIR"
FileOpen $0 "$INSTDIR\${FileMainEXE}" w
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}
SectionEnd
################################################################################
# Helper Functions
; Copies a file to a temporary backup directory and then checks if it is in use
; by attempting to delete the file. If the file is in use an error is displayed
; and the user is given the options to either retry or cancel. If cancel is
; selected then the files are restored.
Function CheckInUse
${If} ${FileExists} "$INSTDIR\$R1"
retry:
ClearErrors
CopyFiles /SILENT "$INSTDIR\$R1" "$TmpVal\$R1"
${Unless} ${Errors}
Delete "$INSTDIR\$R1"
${EndUnless}
${If} ${Errors}
StrCpy $0 "$INSTDIR\$R1"
${WordReplace} "$(^FileError_NoIgnore)" "\r\n" "$\r$\n" "+*" $0
MessageBox MB_RETRYCANCEL|MB_ICONQUESTION "$0" IDRETRY retry
Delete "$TmpVal\$R1"
CopyFiles /SILENT "$TmpVal\*" "$INSTDIR\"
SetOutPath "$INSTDIR"
RmDir /r "$TmpVal"
${OnEndCommon}
Quit
Function CheckExistingInstall
; If there is a pending file copy from a previous uninstall don't allow
; installing until after the system has rebooted.
IfFileExists "$INSTDIR\${FileMainEXE}.moz-upgrade" +1 +4
MessageBox MB_YESNO "$(WARN_RESTART_REQUIRED_UPGRADE)" IDNO +2
Reboot
Quit
; If there is a pending file deletion from a previous uninstall don't allow
; installing until after the system has rebooted.
IfFileExists "$INSTDIR\${FileMainEXE}.moz-delete" +1 +4
MessageBox MB_YESNO "$(WARN_RESTART_REQUIRED_UNINSTALL)" IDNO +2
Reboot
Quit
${If} ${FileExists} "$INSTDIR\${FileMainEXE}"
Banner::show /NOUNLOAD "$(BANNER_CHECK_EXISTING)"
${If} "$TmpVal" == "FoundMessageWindow"
Sleep 5000
${EndIf}
${PushFilesToCheck}
; Store the return value in $TmpVal so it is less likely to be accidentally
; overwritten elsewhere.
${CheckForFilesInUse} $TmpVal
Banner::destroy
${If} "$TmpVal" == "true"
StrCpy $TmpVal "FoundMessageWindow"
${ManualCloseAppPrompt} "${WindowClass}" "$(WARN_MANUALLY_CLOSE_APP_INSTALL)"
StrCpy $TmpVal "true"
${EndIf}
${EndIf}
FunctionEnd
Function DoCopyFiles
StrLen $R2 $R0
${LocateNoDetails} "$R0" "/L=FD" "CopyFile"
FunctionEnd
Function CopyFile
StrCpy $R3 $R8 "" $R2
retry:
ClearErrors
${If} $R6 == ""
${Unless} ${FileExists} "$R1$R3\$R7"
ClearErrors
CreateDirectory "$R1$R3\$R7"
${If} ${Errors}
${LogMsg} "** ERROR Creating Directory: $R1$R3\$R7 **"
StrCpy $0 "$R1$R3\$R7"
StrCpy $0 "$(ERROR_CREATE_DIRECTORY)"
MessageBox MB_RETRYCANCEL|MB_ICONQUESTION "$0" IDRETRY retry
Quit
${Else}
${LogMsg} "Created Directory: $R1$R3\$R7"
${EndIf}
${EndUnless}
${Else}
${Unless} ${FileExists} "$R1$R3"
ClearErrors
CreateDirectory "$R1$R3"
${If} ${Errors}
${LogMsg} "** ERROR Creating Directory: $R1$R3 **"
StrCpy $0 "$R1$R3"
StrCpy $0 "$(ERROR_CREATE_DIRECTORY)"
MessageBox MB_RETRYCANCEL|MB_ICONQUESTION "$0" IDRETRY retry
Quit
${Else}
${LogMsg} "Created Directory: $R1$R3"
${EndIf}
${EndUnless}
${If} ${FileExists} "$R1$R3\$R7"
ClearErrors
Delete "$R1$R3\$R7"
${If} ${Errors}
${LogMsg} "** ERROR Deleting File: $R1$R3\$R7 **"
StrCpy $0 "$R1$R3\$R7"
${WordReplace} "$(^FileError_NoIgnore)" "\r\n" "$\r$\n" "+*" $0
MessageBox MB_RETRYCANCEL|MB_ICONQUESTION "$0" IDRETRY retry
Quit
${EndIf}
${EndIf}
ClearErrors
CopyFiles /SILENT $R9 "$R1$R3"
${If} ${Errors}
${LogMsg} "** ERROR Installing File: $R1$R3\$R7 **"
StrCpy $0 "$R1$R3\$R7"
${WordReplace} "$(^FileError_NoIgnore)" "\r\n" "$\r$\n" "+*" $0
MessageBox MB_RETRYCANCEL|MB_ICONQUESTION "$0" IDRETRY retry
Quit
${Else}
${LogMsg} "Installed File: $R1$R3\$R7"
${EndIf}
; If the file is installed into the installation directory remove the
; installation directory's path from the file path when writing to the
; uninstall.log so it will be a relative path. This allows the same
; helper.exe to be used with zip builds if we supply an uninstall.log.
${WordReplace} "$R1$R3\$R7" "$INSTDIR" "" "+" $R3
${LogUninstall} "File: $R3"
${EndIf}
Push 0
FunctionEnd
Function LaunchApp
ClearErrors
${GetParameters} $0
@ -701,6 +639,10 @@ Function leaveOptions
${MUI_INSTALLOPTIONS_READ} $R0 "options.ini" "Field 3" "State"
StrCmp $R0 "1" +1 +2
StrCpy $InstallType ${INSTALLTYPE_CUSTOM}
${If} $InstallType != ${INSTALLTYPE_CUSTOM}
Call CheckExistingInstall
${EndIf}
FunctionEnd
Function preComponents
@ -751,6 +693,12 @@ Function preStartMenu
${EndIf}
FunctionEnd
Function leaveStartMenu
${If} $InstallType == ${INSTALLTYPE_CUSTOM}
Call CheckExistingInstall
${EndIf}
FunctionEnd
Function preSummary
!insertmacro createSummaryINI
!insertmacro MUI_HEADER_TEXT "$(SUMMARY_PAGE_TITLE)" "$(SUMMARY_PAGE_SUBTITLE)"
@ -760,21 +708,27 @@ Function preSummary
!insertmacro MUI_INSTALLOPTIONS_INITDIALOG "summary.ini"
GetDlgItem $0 $HWNDPARENT 1
System::Call "user32::SetFocus(i r0, i 0x0007, i,i)i"
${MUI_INSTALLOPTIONS_READ} $1 "summary.ini" "Field 2" "HWND"
SendMessage $1 ${WM_SETTEXT} 0 "STR:$INSTDIR"
!insertmacro MUI_INSTALLOPTIONS_SHOW
FunctionEnd
Function leaveSummary
; If there is a pending deletion from a previous uninstall don't allow
; installing until after the system has rebooted.
IfFileExists "$INSTDIR\${FileMainEXE}.moz-delete" +1 +4
MessageBox MB_YESNO "$(WARN_RESTART_REQUIRED_UNINSTALL)" IDNO +2
Reboot
Quit
${If} $InstallType != ${INSTALLTYPE_CUSTOM}
; Set DOMi to be installed
SectionSetFlags ${DOMI_IDX} 1
${EndIf}
; Try to delete the app executable and if we can't delete it try to find the
; app's message window and prompt the user to close the app. This allows
; running an instance that is located in another directory. If for whatever
; reason there is no message window we will just rename the app's files and
; then remove them on restart.
ClearErrors
${DeleteFile} "$INSTDIR\${FileMainEXE}"
${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

Просмотреть файл

@ -549,3 +549,32 @@
${EndIf}
!macroend
!define RemoveDeprecatedKeys "!insertmacro RemoveDeprecatedKeys"
; The files to check if they are in use during (un)install so the restart is
; required message is displayed.
!macro PushFilesToCheck
; The first string to be pushed onto the stack MUST be "end" to indicate
; that there are no more relative file paths to check and the last string
; should be ${FileMainEXE} so if it is in use the CheckForFilesInUse macro
; returns after the first check.
Push "end"
Push "chrome\browser.jar"
Push "chrome\classic.jar"
Push "chrome\comm.jar"
Push "chrome\${AB_CD}.jar"
Push "chrome\pippki.jar"
Push "chrome\reporter.jar"
Push "chrome\toolkit.jar"
Push "AccessibleMarshal.dll"
Push "freebl3.dll"
Push "nssckbi.dll"
Push "nspr4.dll"
Push "nssdbm3.dll"
Push "sqlite3.dll"
Push "xpcom.dll"
Push "crashreporter.exe"
Push "updater.exe"
Push "xpicleanup.exe"
Push "${FileMainEXE}"
!macroend
!define PushFilesToCheck "!insertmacro PushFilesToCheck"

Просмотреть файл

@ -109,6 +109,7 @@ VIAddVersionKey "FileDescription" "${BrandShortName} Helper"
!insertmacro WriteRegStr2
!insertmacro un.ChangeMUIHeaderImage
!insertmacro un.CheckForFilesInUse
!insertmacro un.CleanVirtualStore
!insertmacro un.DeleteRelativeProfiles
!insertmacro un.GetLongPath
@ -160,6 +161,7 @@ ShowUnInstDetails nevershow
*/
; Welcome Page
!define MUI_PAGE_CUSTOMFUNCTION_PRE un.preWelcome
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE un.leaveWelcome
!insertmacro MUI_UNPAGE_WELCOME
; Uninstall Confirm Page
@ -182,6 +184,9 @@ UninstPage custom un.preConfirm un.leaveConfirm
!insertmacro MUI_UNPAGE_FINISH
; Use the default dialog for IDD_VERIFY for a simple Banner
ChangeUI IDD_VERIFY "${NSISDIR}\Contrib\UIs\default.exe"
################################################################################
# Install Sections
; Empty section required for the installer to compile as an uninstaller
@ -375,6 +380,28 @@ Function un.preWelcome
${EndIf}
FunctionEnd
Function un.leaveWelcome
${If} ${FileExists} "$INSTDIR\${FileMainEXE}"
Banner::show /NOUNLOAD "$(BANNER_CHECK_EXISTING)"
${If} "$TmpVal" == "FoundMessageWindow"
Sleep 5000
${EndIf}
${PushFilesToCheck}
${un.CheckForFilesInUse} $TmpVal
Banner::destroy
${If} "$TmpVal" == "true"
StrCpy $TmpVal "FoundMessageWindow"
${un.ManualCloseAppPrompt} "${WindowClass}" "$(WARN_MANUALLY_CLOSE_APP_UNINSTALL)"
StrCpy $TmpVal "true"
${EndIf}
${EndIf}
FunctionEnd
Function un.preConfirm
${If} ${FileExists} "$INSTDIR\distribution\modern-header.bmp"
${AndIf} $hHeaderBitmap == ""
@ -393,6 +420,8 @@ Function un.preConfirm
SetCtlColors $1 0x000000 0xFFFFEE
ShowWindow $1 ${SW_HIDE}
System::Call "user32::SetFocus(i r0, i 0x0007, i,i)i"
${MUI_INSTALLOPTIONS_READ} $1 "unconfirm.ini" "Field 2" "HWND"
SendMessage $1 ${WM_SETTEXT} 0 "STR:$INSTDIR"
!insertmacro MUI_INSTALLOPTIONS_SHOW
FunctionEnd
@ -415,7 +444,6 @@ Function un.leaveConfirm
; running an instance that is located in another directory. If for whatever
; reason there is no message window we will just rename the app's files and
; then remove them on restart if they are in use.
StrCpy $TmpVal ""
ClearErrors
${DeleteFile} "$INSTDIR\${FileMainEXE}"
${If} ${Errors}

Просмотреть файл

@ -66,6 +66,8 @@ SHORTCUTS_PAGE_SUBTITLE=Create Program Icons
SUMMARY_PAGE_TITLE=Summary
SUMMARY_PAGE_SUBTITLE=Ready to start installing $BrandShortName
SUMMARY_INSTALLED_TO=$BrandShortName will be installed to the following location:
SUMMARY_REBOOT_REQUIRED_INSTALL=A restart of your computer may be required to complete the installation.
SUMMARY_REBOOT_REQUIRED_UNINSTALL=A restart of your computer may be required to complete the uninstall.
SUMMARY_CLICK=Click Install to continue.
SURVEY_TEXT=&Tell us what you thought of $BrandShortName
LAUNCH_TEXT=&Launch $BrandShortName now
@ -74,13 +76,16 @@ CREATE_ICONS_DESC=Create icons for $BrandShortName:
ICONS_DESKTOP=On my &Desktop
ICONS_STARTMENU=In my &Start Menu Programs folder
ICONS_QUICKLAUNCH=In my &Quick Launch bar
WARN_MANUALLY_CLOSE_APP_INSTALL=$BrandShortName must be closed to proceed with the installation.\n\nPlease close $BrandShortName to continue.
WARN_MANUALLY_CLOSE_APP_UNINSTALL=$BrandShortName must be closed to proceed with the uninstall.\n\nPlease close $BrandShortName to continue.
WARN_MANUALLY_CLOSE_APP_LAUNCH=$BrandShortName is already running.\n\nPlease close $BrandShortName prior to launching the version you have just installed.
WARN_WRITE_ACCESS=You don't have access to write to the installation directory.\n\nClick OK to select a different directory.
WARN_DISK_SPACE=You don't have sufficient disk space to install to this location.\n\nClick OK to select a different location.
WARN_UNSUPPORTED_MSG=Sorry, $BrandShortName can't be installed. This version of $BrandShortName requires ${MinUnsupportedVer} or newer.
WARN_RESTART_REQUIRED_UNINSTALL=Your computer must be restarted to complete a previous uninstall of $BrandShortName. Do you want to reboot now?
ERROR_CREATE_DIRECTORY=Error creating directory:\n\n$0\n\nClick Cancel to stop the installation or\nRetry to try again.
WARN_RESTART_REQUIRED_UPGRADE=Your computer must be restarted to complete a previous upgrade of $BrandShortName. Do you want to reboot now?
ERROR_CREATE_DIRECTORY_PREFIX=Error creating directory:
ERROR_CREATE_DIRECTORY_SUFFIX=Click Cancel to stop the installation or\nRetry to try again.
UN_CONFIRM_PAGE_TITLE=Uninstall $BrandFullName
UN_CONFIRM_PAGE_SUBTITLE=Remove $BrandFullName from your computer.
@ -89,6 +94,8 @@ UN_CONFIRM_CLICK=Click Uninstall to continue.
UN_REMOVE_PROFILES=&Remove my $BrandShortName personal data and customizations
UN_REMOVE_PROFILES_DESC=This will permanently remove your bookmarks, saved passwords, cookies and customizations. You may wish to keep this information if you plan on installing another version of $BrandShortName in the future.
BANNER_CHECK_EXISTING=Checking existing installation…
STATUS_INSTALL_APP=Installing $BrandShortName…
STATUS_INSTALL_LANG=Installing Language Files (${AB_CD})…
STATUS_INSTALL_OPTIONAL=Installing Optional Components…

Просмотреть файл

@ -490,13 +490,11 @@
WriteINIStr "$PLUGINSDIR\summary.ini" "Field 1" Top "5"
WriteINIStr "$PLUGINSDIR\summary.ini" "Field 1" Bottom "15"
; XXXrstrong - a side affect of using a READONLY textbox is if the path is
; longer than the visible area of the textbox it will display the characters
; at the end and the beginning of the path will be hidden. Since the path has
; to be greater than 74 characters in length I'm not going to spend any
; cycles trying to come up with a workaround.
WriteINIStr "$PLUGINSDIR\summary.ini" "Field 2" Type "text"
WriteINIStr "$PLUGINSDIR\summary.ini" "Field 2" state "$INSTDIR"
; The contents of this control must be set as follows in the pre function
; ${MUI_INSTALLOPTIONS_READ} $1 "summary.ini" "Field 2" "HWND"
; SendMessage $1 ${WM_SETTEXT} 0 "STR:$INSTDIR"
WriteINIStr "$PLUGINSDIR\summary.ini" "Field 2" state ""
WriteINIStr "$PLUGINSDIR\summary.ini" "Field 2" Left "0"
WriteINIStr "$PLUGINSDIR\summary.ini" "Field 2" Right "-1"
WriteINIStr "$PLUGINSDIR\summary.ini" "Field 2" Top "17"
@ -509,6 +507,18 @@
WriteINIStr "$PLUGINSDIR\summary.ini" "Field 3" Right "-1"
WriteINIStr "$PLUGINSDIR\summary.ini" "Field 3" Top "130"
WriteINIStr "$PLUGINSDIR\summary.ini" "Field 3" Bottom "150"
${If} "$TmpVal" == "true"
WriteINIStr "$PLUGINSDIR\summary.ini" "Field 4" Type "label"
WriteINIStr "$PLUGINSDIR\summary.ini" "Field 4" Text "$(SUMMARY_REBOOT_REQUIRED_INSTALL)"
WriteINIStr "$PLUGINSDIR\summary.ini" "Field 4" Left "0"
WriteINIStr "$PLUGINSDIR\summary.ini" "Field 4" Right "-1"
WriteINIStr "$PLUGINSDIR\summary.ini" "Field 4" Top "35"
WriteINIStr "$PLUGINSDIR\summary.ini" "Field 4" Bottom "45"
WriteINIStr "$PLUGINSDIR\summary.ini" "Settings" NumFields "4"
${EndIf}
!macroend
!macro un.createUnConfirmINI
@ -521,13 +531,11 @@
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 1" Top "5"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 1" Bottom "15"
; XXXrstrong - a side affect of using a READONLY textbox is if the path is
; longer than the visible area of the textbox it will display the characters
; at the end and the beginning of the path will be hidden. Since the path has
; to be greater than 74 characters in length I'm not going to spend any
; cycles trying to come up with a workaround.
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" Type "text"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" State "$INSTDIR"
; The contents of this control must be set as follows in the pre function
; ${MUI_INSTALLOPTIONS_READ} $1 "unconfirm.ini" "Field 2" "HWND"
; SendMessage $1 ${WM_SETTEXT} 0 "STR:$INSTDIR"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" State ""
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" Left "0"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" Right "-1"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 2" Top "17"
@ -557,6 +565,22 @@
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 5" Right "-1"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 5" Top "130"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 5" Bottom "150"
${If} "$TmpVal" == "true"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 6" Type "label"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 6" Text "$(SUMMARY_REBOOT_REQUIRED_UNINSTALL)"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 6" Left "0"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 6" Right "-1"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 6" Top "35"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 6" Bottom "45"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Settings" NumFields "6"
; To insert this control reset Top / Bottom for controls below this one
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Top "55"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 3" Bottom "65"
WriteINIStr "$PLUGINSDIR\unconfirm.ini" "Field 4" Top "67"
${EndIf}
!macroend
/**
@ -630,6 +654,105 @@
################################################################################
# Macros for handling files in use
/**
* Checks for files in use.
*
* Example usage:
*
* ; The first string to be pushed onto the stack MUST be "end" to indicate
* ; that there are no more relative file paths to check.
* Push "end"
* Push "chrome\toolkit.jar"
* Push "freebl3.dll"
* ; The last file pushed should be the app's main exe so if it is in use this
* ; macro will return after the first check.
* Push "${FileMainEXE}"
* ${CheckForFilesInUse} $R9
*
* !IMPORTANT - this macro uses the $R7, $R8, and $R9 registers and makes no
* attempt to restore their original values.
*
* @return _RESULT
* false if all of the files popped from the stack are not in use.
* True if any of the files popped from the stack are in use.
* $R7 = Temporary backup directory where the files will be copied to.
* $R8 = value popped from the stack. This will either be a relative file path
* from the $INSTDIR or "end" to indicate that there are no additional
* files to check.
* $R9 = _RESULT
*/
!macro CheckForFilesInUse
!ifndef ${_MOZFUNC_UN}CheckForFilesInUse
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!define ${_MOZFUNC_UN}CheckForFilesInUse "!insertmacro ${_MOZFUNC_UN}CheckForFilesInUseCall"
Function ${_MOZFUNC_UN}CheckForFilesInUse
; Create a temporary backup directory.
GetTempFileName $R7 "$INSTDIR"
Delete "$R7"
SetOutPath "$R7"
StrCpy $R9 "false"
start:
Pop $R8
StrCmp "$R8" "end" end +1
IfFileExists "$INSTDIR\$R8" +1 start
ClearErrors
CopyFiles /SILENT "$INSTDIR\$R8" "$R7\$R8"
IfErrors +4 +1
Delete "$INSTDIR\$R8"
IfErrors +1 start
Delete "$R7\$R8"
StrCpy $R9 "true"
end:
SetOutPath "$INSTDIR"
CopyFiles /SILENT "$R7\*" "$INSTDIR\"
RmDir /r "$R7"
ClearErrors
Push $R9
FunctionEnd
!verbose pop
!endif
!macroend
!macro CheckForFilesInUseCall _RESULT
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Call CheckForFilesInUse
Pop ${_RESULT}
!verbose pop
!macroend
!macro un.CheckForFilesInUseCall _RESULT
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Call un.CheckForFilesInUse
Pop ${_RESULT}
!verbose pop
!macroend
!macro un.CheckForFilesInUse
!ifndef un.CheckForFilesInUse
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!undef _MOZFUNC_UN
!define _MOZFUNC_UN "un."
!insertmacro CheckForFilesInUse
!undef _MOZFUNC_UN
!define _MOZFUNC_UN
!verbose pop
!endif
!macroend
/**
* The macros below will automatically prepend un. to the function names when
* they are defined (e.g. !define un.RegCleanMain).
@ -3470,6 +3593,176 @@
!verbose pop
!macroend
/**
* Copies files from a source directory to a destination directory with logging
* to the uninstall.log. If any destination files are in use a reboot will be
* necessary to complete the installation and the reboot flag (see IfRebootFlag
* in the NSIS documentation).
*
* @param _PATH_TO_SOURCE
* Source path to copy the files from. This must not end with a \.
*
* @param _PATH_TO_DESTINATION
* Destination path to copy the files to. This must not end with a \.
*
* @param _PREFIX_ERROR_CREATEDIR
* Prefix for the directory creation error message. The directory path
* will be inserted below this string.
*
* @param _SUFFIX_ERROR_CREATEDIR
* Prefix for the directory creation error message. The directory path
* will be inserted above this string.
*
* $0 = destination file's parent directory used in the create_dir label
* $R0 = copied value from $R6 (e.g. _PATH_TO_SOURCE)
* $R1 = copied value from $R7 (e.g. _PATH_TO_DESTINATION)
* $R2 = string length of the path to source
* $R3 = relative path from the path to source
* $R4 = copied value from $R8 (e.g. _PREFIX_ERROR_CREATEDIR)
* $R5 = copied value from $R9 (e.g. _SUFFIX_ERROR_CREATEDIR)
* note: the LocateNoDetails macro uses these registers so we copy the values
* to other registers.
* $R6 = initially _PATH_TO_SOURCE and then set to "size" ($R6="" if directory,
* $R6="0" if file with /S=)"path\name" in callback
* $R7 = initially _PATH_TO_DESTINATION and then set to "name" in callback
* $R8 = initially _PREFIX_ERROR_CREATEDIR and then set to "path" in callback
* $R9 = initially _SUFFIX_ERROR_CREATEDIR and then set to "path\name" in
* callback
*/
!macro CopyFilesFromDir
!ifndef CopyFilesFromDir
!insertmacro LocateNoDetails
!insertmacro OnEndCommon
!insertmacro WordReplace
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!define CopyFilesFromDir "!insertmacro CopyFilesFromDirCall"
Function CopyFilesFromDir
Exch $R9
Exch 1
Exch $R8
Exch 2
Exch $R7
Exch 3
Exch $R6
Push $R5
Push $R4
Push $R3
Push $R2
Push $R1
Push $R0
Push $0
StrCpy $R0 "$R6"
StrCpy $R1 "$R7"
StrCpy $R4 "$R8"
StrCpy $R5 "$R9"
StrLen $R2 $R0
${LocateNoDetails} "$R0" "/L=FD" "CopyFileCallback"
Pop $0
Pop $R0
Pop $R1
Pop $R2
Pop $R3
Pop $R4
Pop $R5
Exch $R6
Exch 3
Exch $R7
Exch 2
Exch $R8
Exch 1
Exch $R9
FunctionEnd
Function CopyFileCallback
StrCpy $R3 $R8 "" $R2 ; $R3 always begins with a \.
retry:
ClearErrors
StrCmp $R6 "" +1 copy_file
IfFileExists "$R1$R3\$R7" end +1
StrCpy $0 "$R1$R3\$R7"
create_dir:
ClearErrors
CreateDirectory "$0"
IfFileExists "$0" +1 err_create_dir ; protect against looping.
${LogMsg} "Created Directory: $0"
StrCmp $R6 "" end copy_file
err_create_dir:
${LogMsg} "** ERROR Creating Directory: $0 **"
MessageBox MB_RETRYCANCEL|MB_ICONQUESTION "$R4$\r$\n$\r$\n$0$\r$\n$\r$\n$R5" IDRETRY retry
${OnEndCommon}
Quit
copy_file:
StrCpy $0 "$R1$R3"
IfFileExists "$0" +1 create_dir
ClearErrors
${DeleteFile} "$R1$R3\$R7"
IfErrors +1 dest_clear
ClearErrors
Rename "$R1$R3\$R7" "$R1$R3\$R7.moz-delete"
IfErrors +1 reboot_delete
; file will replace destination file on reboot
Rename "$R9" "$R9.moz-upgrade"
CopyFiles /SILENT "$R9.moz-upgrade" "$R1$R3"
Rename /REBOOTOK "$R1$R3\$R7.moz-upgrade" "$R1$R3\$R7"
${LogMsg} "Copied File: $R1$R3\$R7.moz-upgrade"
${LogMsg} "Delayed Install File (Reboot Required): $R1$R3\$R7"
GoTo log_uninstall
; file will be deleted on reboot
reboot_delete:
CopyFiles /SILENT $R9 "$R1$R3"
Delete /REBOOTOK "$R1$R3\$R7.moz-delete"
${LogMsg} "Installed File: $R1$R3\$R7"
${LogMsg} "Delayed Delete File (Reboot Required): $R1$R3\$R7.moz-delete"
GoTo log_uninstall
; destination file doesn't exist - coast is clear
dest_clear:
CopyFiles /SILENT $R9 "$R1$R3"
${LogMsg} "Installed File: $R1$R3\$R7"
log_uninstall:
; If the file is installed into the installation directory remove the
; installation directory's path from the file path when writing to the
; uninstall.log so it will be a relative path. This allows the same
; helper.exe to be used with zip builds if we supply an uninstall.log.
${WordReplace} "$R1$R3\$R7" "$INSTDIR" "" "+" $R3
${LogUninstall} "File: $R3"
end:
Push 0
FunctionEnd
!verbose pop
!endif
!macroend
!macro CopyFilesFromDirCall _PATH_TO_SOURCE _PATH_TO_DESTINATION \
_PREFIX_ERROR_CREATEDIR _SUFFIX_ERROR_CREATEDIR
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Push "${_PATH_TO_SOURCE}"
Push "${_PATH_TO_DESTINATION}"
Push "${_PREFIX_ERROR_CREATEDIR}"
Push "${_SUFFIX_ERROR_CREATEDIR}"
Call CopyFilesFromDir
!verbose pop
!macroend
/**
* Parses the uninstall.log to unregister dll's, remove files, and remove
* empty directories for this installation.
@ -4132,10 +4425,24 @@
Function UninstallOnInitCommon
; Prevent launching the application when a reboot is required and this
; executable is the main application executable
IfFileExists "$EXEDIR\${FileMainEXE}.moz-upgrade" +1 +4
MessageBox MB_YESNO "$(WARN_RESTART_REQUIRED_UPGRADE)" IDNO +2
Reboot
Quit ; Nothing initialized so no need to call OnEndCommon
GetFullPathName $INSTDIR "$EXEDIR\.."
${GetLongPath} "$INSTDIR" $INSTDIR
IfFileExists "$INSTDIR\${FileMainEXE}" +2 +1
Abort
Quit ; Nothing initialized so no need to call OnEndCommon
; Prevent all operations (e.g. set as default, postupdate, etc.) when a
; reboot is required and the executable launched is helper.exe
IfFileExists "$INSTDIR\${FileMainEXE}.moz-upgrade" +1 +4
MessageBox MB_YESNO "$(WARN_RESTART_REQUIRED_UPGRADE)" IDNO +2
Reboot
Quit ; Nothing initialized so no need to call OnEndCommon
${GetParameters} $R0
@ -4209,14 +4516,14 @@
finish:
${UnloadUAC}
System::Call "shell32::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)"
Quit
Quit ; Nothing initialized so no need to call OnEndCommon
continue:
; If the uninstall.log does not exist don't perform uninstall
; operations. This prevents running the uninstaller for zip builds.
IfFileExists "$INSTDIR\uninstall\uninstall.log" +2 +1
Quit
Quit ; Nothing initialized so no need to call OnEndCommon
; Require elevation if the user can elevate
${ElevateUAC}
@ -4234,7 +4541,7 @@
${DeleteFile} "$EXEDIR\uninstaller.exe"
${UnloadUAC}
SetErrorLevel 0
Quit
Quit ; Nothing initialized so no need to call OnEndCommon
FunctionEnd
@ -4328,7 +4635,6 @@
* @param _WARN_DISK_SPACE
* Message displayed when there isn't enough disk space to perform the
* installation.
* $INSTDIR.
* @param _WARN_WRITE_ACCESS
* Message displayed when the installer does not have write access to
* $INSTDIR.