diff --git a/mozilla/browser/installer/windows/nsis/installer.nsi b/mozilla/browser/installer/windows/nsis/installer.nsi index c07f7748822..5398ba0f349 100755 --- a/mozilla/browser/installer/windows/nsis/installer.nsi +++ b/mozilla/browser/installer/windows/nsis/installer.nsi @@ -85,6 +85,11 @@ Var fhUninstallLog !insertmacro DriveSpace !insertmacro GetParent +; NSIS provided macros that we have overridden +!include overrides.nsh +!insertmacro LocateNoDetails +!insertmacro TextCompareNoDetails + ; The following includes are custom. !include branding.nsi !include defines.nsi @@ -100,13 +105,10 @@ Var fhUninstallLog !insertmacro CreateRegKey !insertmacro CanWriteToInstallDir !insertmacro CheckDiskSpace +!insertmacro DisplayCopyErrMsg !insertmacro GetExistingInstallPath !insertmacro IsVista -!include overrides.nsh -!insertmacro LocateNoDetails -!insertmacro TextCompareNoDetails - Name "${BrandFullName}" OutFile "setup.exe" InstallDirRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal} (${AppVersion})" "InstallLocation" @@ -191,8 +193,9 @@ Section "-Application" Section1 SetDetailsPrint none SetOutPath $INSTDIR - ; Try to delete the app executable and if we can't delete it try to close the - ; app. This allows running an instance that is located in another directory. + ; 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. ClearErrors ${If} ${FileExists} "$INSTDIR\${FileMainEXE}" ${DeleteFile} "$INSTDIR\${FileMainEXE}" @@ -202,8 +205,21 @@ Section "-Application" Section1 ${CloseApp} "true" $(WARN_APP_RUNNING_INSTALL) ; Try to delete it again to prevent launching the app while we are ; installing. - ${DeleteFile} "$INSTDIR\${FileMainEXE}" ClearErrors + ${DeleteFile} "$INSTDIR\${FileMainEXE}" + ${If} ${Errors} + ClearErrors + ; Try closing the app a second time + ${CloseApp} "true" $(WARN_APP_RUNNING_INSTALL) + retry: + ClearErrors + ${DeleteFile} "$INSTDIR\${FileMainEXE}" + ${If} ${Errors} + ; Fallback to the FileError_NoIgnore error with retry/cancel options + ${DisplayCopyErrMsg} "${FileMainEXE}" + GoTo retry + ${EndIf} + ${EndIf} ${EndIf} ; During an install Vista checks if a new entry is added under the uninstall @@ -844,12 +860,16 @@ 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 **" + ${DisplayCopyErrMsg} "$R7" + GoTo retry ${Else} ${LogMsg} "Created Directory: $R1$R3\$R7" ${EndIf} @@ -860,18 +880,25 @@ Function CopyFile CreateDirectory "$R1$R3" ${If} ${Errors} ${LogMsg} "** ERROR Creating Directory: $R1$R3 **" + ${DisplayCopyErrMsg} "$R3" + GoTo retry ${Else} ${LogMsg} "Created Directory: $R1$R3" ${EndIf} ${EndUnless} ${If} ${FileExists} "$R1$R3\$R7" Delete "$R1$R3\$R7" + ${If} ${Errors} + ${DisplayCopyErrMsg} "$R7" + GoTo retry + ${EndIf} ${EndIf} ClearErrors CopyFiles /SILENT $R9 "$R1$R3" ${If} ${Errors} - ; XXXrstrong - what should we do if there is an error installing a file? ${LogMsg} "** ERROR Installing File: $R1$R3\$R7 **" + ${DisplayCopyErrMsg} "$R7" + GoTo retry ${Else} ${LogMsg} "Installed File: $R1$R3\$R7" ${EndIf} @@ -1200,6 +1227,7 @@ Function .onInit ReadINIStr $0 $R1 "Install" "CloseAppNoPrompt" ${If} $0 == "true" + ; Try to close the app if the exe is in use. ClearErrors ${If} ${FileExists} "$INSTDIR\${FileMainEXE}" ${DeleteFile} "$INSTDIR\${FileMainEXE}" @@ -1207,7 +1235,18 @@ Function .onInit ${If} ${Errors} ClearErrors ${CloseApp} "false" "" + ClearErrors ${DeleteFile} "$INSTDIR\${FileMainEXE}" + ; If unsuccessful try one more time and if it still fails Quit + ${If} ${Errors} + ClearErrors + ${CloseApp} "false" "" + ClearErrors + ${DeleteFile} "$INSTDIR\${FileMainEXE}" + ${If} ${Errors} + Quit + ${EndIf} + ${EndIf} ${EndIf} ${EndIf} diff --git a/mozilla/browser/installer/windows/nsis/uninstaller.nsi b/mozilla/browser/installer/windows/nsis/uninstaller.nsi index 17e1e05c1b5..1f8e4172db1 100755 --- a/mozilla/browser/installer/windows/nsis/uninstaller.nsi +++ b/mozilla/browser/installer/windows/nsis/uninstaller.nsi @@ -374,8 +374,15 @@ Function un.preInstFiles ClearErrors ${un.CloseApp} "true" $(WARN_APP_RUNNING_UNINSTALL) ; Delete the app exe to prevent launching the app while we are uninstalling. - ${DeleteFile} "$INSTDIR\${FileMainEXE}" ClearErrors + ${DeleteFile} "$INSTDIR\${FileMainEXE}" + ${If} ${Errors} + ClearErrors + ${un.CloseApp} "true" $(WARN_APP_RUNNING_UNINSTALL) + ClearErrors + ; Try one more time and if that fails uninstall what ever we are able to. + ${DeleteFile} "$INSTDIR\${FileMainEXE}" + ${EndIf} ${EndIf} FunctionEnd diff --git a/mozilla/toolkit/mozapps/installer/windows/nsis/common.nsh b/mozilla/toolkit/mozapps/installer/windows/nsis/common.nsh index 3e236cca492..dbe654aeed7 100755 --- a/mozilla/toolkit/mozapps/installer/windows/nsis/common.nsh +++ b/mozilla/toolkit/mozapps/installer/windows/nsis/common.nsh @@ -1044,13 +1044,16 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack /** * Posts WM_QUIT to the application's message window which is found using the - * message window's class. + * message window's class. This macro uses the nsProcess plugin available + * from http://nsis.sourceforge.net/NsProcess_plugin + * * @param _MSG * The message text to display in the message box. * @param _PROMPT * If false don't prompt the user and automatically exit the * application if it is running. * + * $R6 = return value for nsProcess::_FindProcess and nsProcess::_KillProcess * $R7 = value returned from FindWindow * $R8 = _PROMPT * $R9 = _MSG @@ -1067,23 +1070,42 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack Exch 1 Exch $R8 Push $R7 + Push $R6 loop: - FindWindow $R7 "${WindowClass}" - IntCmp $R7 0 end + Push $R6 + nsProcess::_FindProcess /NOUNLOAD "${FileMainEXE}" + Pop $R6 + StrCmp $R6 0 0 end + StrCmp $R8 "false" +2 0 MessageBox MB_OKCANCEL|MB_ICONQUESTION "$R9" IDCANCEL exit 0 + FindWindow $R7 "${WindowClass}" + IntCmp $R7 0 +4 System::Call 'user32::PostMessage(i r17, i ${WM_QUIT}, i 0, i 0)' # The amount of time to wait for the app to shutdown before prompting again - Sleep 4000 + Sleep 5000 + + Push $R6 + nsProcess::_FindProcess /NOUNLOAD "${FileMainEXE}" + Pop $R6 + StrCmp $R6 0 0 end + Push $R6 + nsProcess::_KillProcess /NOUNLOAD "${FileMainEXE}" + Pop $R6 + Sleep 2000 + Goto loop exit: + nsProcess::_Unload Quit end: + nsProcess::_Unload + Pop $R6 Pop $R7 Exch $R8 Exch 1 @@ -1769,3 +1791,58 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack !endif !macroend +/** + * Displays a error message when a file can't be copied. + * + * $0 = file name inserted into the error message + */ +!macro DisplayCopyErrMsg + + !ifndef ${_MOZFUNC_UN}DisplayCopyErrMsg + !verbose push + !verbose ${_MOZFUNC_VERBOSE} + !define ${_MOZFUNC_UN}DisplayCopyErrMsg "!insertmacro ${_MOZFUNC_UN}DisplayCopyErrMsgCall" + + Function ${_MOZFUNC_UN}DisplayCopyErrMsg + Exch $0 + + MessageBox MB_RETRYCANCEL|MB_ICONQUESTION "$(^FileError_NoIgnore)" IDRETRY +2 + Quit + + Exch $0 + FunctionEnd + + !verbose pop + !endif +!macroend + +!macro DisplayCopyErrMsgCall _FILE + !verbose push + !verbose ${_MOZFUNC_VERBOSE} + Push "${_FILE}" + Call DisplayCopyErrMsg + !verbose pop +!macroend + +!macro un.DisplayCopyErrMsgCall _FILE + !verbose push + !verbose ${_MOZFUNC_VERBOSE} + Push "${_FILE}" + Call un.DisplayCopyErrMsg + !verbose pop +!macroend + +!macro un.DisplayCopyErrMsg + !ifndef un.DisplayCopyErrMsg + !verbose push + !verbose ${_MOZFUNC_VERBOSE} + !undef _MOZFUNC_UN + !define _MOZFUNC_UN "un." + + !insertmacro DisplayCopyErrMsg + + !undef _MOZFUNC_UN + !define _MOZFUNC_UN + !verbose pop + !endif +!macroend diff --git a/mozilla/toolkit/mozapps/installer/windows/nsis/makensis.mk b/mozilla/toolkit/mozapps/installer/windows/nsis/makensis.mk index 82163eb4b1f..32668cae495 100755 --- a/mozilla/toolkit/mozapps/installer/windows/nsis/makensis.mk +++ b/mozilla/toolkit/mozapps/installer/windows/nsis/makensis.mk @@ -48,6 +48,7 @@ SFX_MODULE ?= $(error SFX_MODULE is not defined) TOOLKIT_NSIS_FILES = \ common.nsh \ locales.nsi \ + nsProcess.dll \ overrides.nsh \ ShellLink.dll \ version.nsh \ diff --git a/mozilla/toolkit/mozapps/installer/windows/nsis/nsProcess.dll b/mozilla/toolkit/mozapps/installer/windows/nsis/nsProcess.dll new file mode 100755 index 00000000000..86138f69ec4 Binary files /dev/null and b/mozilla/toolkit/mozapps/installer/windows/nsis/nsProcess.dll differ