Bug 336469 - use new APIs in Vista to register file and protocol handlers (installer). r=sspitzer

This commit is contained in:
rob_strong%exchangecode.com 2006-09-19 20:13:10 +00:00
Родитель 3b549d2556
Коммит b8be1bb361
4 изменённых файлов: 404 добавлений и 11 удалений

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

@ -8,3 +8,4 @@
!define FileMainEXE "firefox.exe"
!define WindowClass "FirefoxMessageWindow"
!define DDEApplication "Firefox"

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

@ -83,6 +83,7 @@ Var fhUninstallLog
!insertmacro GetOptions
!insertmacro GetRoot
!insertmacro DriveSpace
!insertmacro GetParent
; The following includes are custom.
!include branding.nsi
@ -96,10 +97,11 @@ Var fhUninstallLog
!insertmacro CloseApp
!insertmacro WriteRegStr2
!insertmacro WriteRegDWORD2
!insertmacro WriteRegStrHKCR
!insertmacro CreateRegKey
!insertmacro CanWriteToInstallDir
!insertmacro CheckDiskSpace
!insertmacro GetExistingInstallPath
!insertmacro IsVista
!include overrides.nsh
!insertmacro LocateNoDetails
@ -440,7 +442,7 @@ Section "-Application" Section1
; overwrite other installs of the same application.
${StrFilter} "${FileMainEXE}" "+" "" "" $R9
StrCpy $0 "Software\Clients\StartMenuInternet\$R9"
${WriteRegStr2} $TmpVal "$0" "" "${BrandFullNameInternal}" 0
${WriteRegStr2} $TmpVal "$0" "" "${BrandShortName}" 0
StrCpy $0 "Software\Clients\StartMenuInternet\$R9\DefaultIcon"
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\",0"
@ -449,14 +451,14 @@ Section "-Application" Section1
; The Reinstall Command is defined at
; http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_adv/registeringapps.asp
StrCpy $0 "Software\Clients\StartMenuInternet\$R9\InstallInfo"
StrCpy $1 "$\"$INSTDIR\uninstall\uninst.exe$\" /ua $\"${AppVersion} (${AB_CD})$\" /hs browser"
StrCpy $1 "$\"$INSTDIR\uninstall\uninst.exe$\" /HideShortcuts"
${WriteRegStr2} $TmpVal "$0" "HideIconsCommand" "$1" 0
${WriteRegDWORD2} $TmpVal "$0" "IconsVisible" 1 0
StrCpy $0 "Software\Clients\StartMenuInternet\$R9\InstallInfo"
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\" -silent -setDefaultBrowser"
${WriteRegStr2} $TmpVal "$0" "ReinstallCommand" "$1" 0
StrCpy $1 "$\"$INSTDIR\uninstall\uninst.exe$\" /ua $\"${AppVersion} (${AB_CD})$\" /ss browser"
StrCpy $1 "$\"$INSTDIR\uninstall\uninst.exe$\" /ShowShortcuts"
${WriteRegStr2} $TmpVal "$0" "ShowIconsCommand" "$1" 0
StrCpy $0 "Software\Clients\StartMenuInternet\$R9\shell\open\command"
@ -467,14 +469,189 @@ Section "-Application" Section1
StrCpy $0 "Software\Clients\StartMenuInternet\$R9\shell\properties\command"
${WriteRegStr2} $TmpVal "$0" "" "$INSTDIR\${FileMainEXE} -preferences" 0
${IsVista} $R9
${If} $R9 == "true"
; For Vista these keys and name / value pairs may need to be created during
; install.
ReadRegStr $0 HKLM "Software\Classes\.shtml" "Content Type"
${If} $0 == ""
StrCpy $0 "Software\Classes\.shtml"
${WriteRegStr2} $TmpVal "$0" "" "FirefoxHTML" 0
${WriteRegStr2} $TmpVal "$0" "Content Type" "text/html" 0
${WriteRegStr2} $TmpVal "$0" "PerceivedType" "text" 0
${EndIf}
ReadRegStr $0 HKLM "Software\Classes\.xht" "Content Type"
${If} $0 == ""
StrCpy $0 "Software\Classes\.xht"
${WriteRegStr2} $TmpVal "$0" "" "FirefoxHTML" 0
${WriteRegStr2} $TmpVal "$0" "Content Type" "application/xhtml+xml" 0
${EndIf}
ReadRegStr $0 HKLM "Software\Classes\.xhtml" "Content Type"
${If} $0 == ""
StrCpy $0 "Software\Classes\.xhtml"
${WriteRegStr2} $TmpVal "$0" "" "FirefoxHTML" 0
${WriteRegStr2} $TmpVal "$0" "Content Type" "application/xhtml+xml" 0
${EndIf}
ReadRegStr $0 HKLM "Software\Classes\gopher\shell\open\command" ""
${If} $0 == ""
StrCpy $0 "Software\Classes\gopher"
${WriteRegStr2} $TmpVal "$0" "" "URL:Gopher Protocol" 0
${WriteRegStr2} $TmpVal "$0" "URL Protocol" "" 0
${WriteRegDWORD2} $TmpVal "$0" "EditFlags" 2 0
StrCpy $0 "Software\Classes\gopher\DefaultIcon"
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\",0"
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
StrCpy $0 "Software\Classes\gopher\shell\open\command"
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\" -url $\"%1$\""
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
StrCpy $0 "Software\Classes\gopher\shell\open\ddeexec"
StrCpy $1 "$\"%1$\",,0,0,,,,"
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
${WriteRegStr2} $TmpVal "$0" "NoActivateHandler" "" 0
StrCpy $0 "Software\Classes\gopher\shell\open\ddeexec\Application"
${WriteRegStr2} $TmpVal "$0" "" "${DDEApplication}" 0
StrCpy $0 "Software\Classes\gopher\shell\open\ddeexec\ifexec"
StrCpy $1 ",,0,0,,,,"
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
StrCpy $0 "Software\Classes\gopher\shell\open\ddeexec\Topic"
${WriteRegStr2} $TmpVal "$0" "" "WWW_OpenURL" 0
${EndIf}
; Only create the key and its children if it doesn't exist
ReadRegStr $0 HKLM "Software\Classes\chrome\shell\open\command" ""
${If} $0 == ""
StrCpy $0 "Software\Classes\chrome"
${WriteRegStr2} $TmpVal "$0" "" "URL:Chrome Protocol" 0
${WriteRegStr2} $TmpVal "$0" "URL Protocol" "" 0
${WriteRegDWORD2} $TmpVal "$0" "EditFlags" 2 0
StrCpy $0 "Software\Classes\chrome\DefaultIcon"
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\",0"
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
StrCpy $0 "Software\Classes\chrome\shell\open\command"
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\" -url $\"%1$\""
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
StrCpy $0 "Software\Classes\chrome\shell\open\ddeexec"
StrCpy $1 "$\"%1$\",,0,0,,,,"
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
${WriteRegStr2} $TmpVal "$0" "NoActivateHandler" "" 0
StrCpy $0 "Software\Classes\chrome\shell\open\ddeexec\Application"
${WriteRegStr2} $TmpVal "$0" "" "${DDEApplication}" 0
StrCpy $0 "Software\Classes\gopher\shell\open\ddeexec\ifexec"
StrCpy $1 ",,0,0,,,,"
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
StrCpy $0 "Software\Classes\chrome\shell\open\ddeexec\Topic"
${WriteRegStr2} $TmpVal "$0" "" "WWW_OpenURL" 0
${EndIf}
; Always set the file and protocol handlers since they may specify a
; different path and the path is used by Vista when setting associations.
StrCpy $0 "Software\Classes\FirefoxURL"
${WriteRegStr2} $TmpVal "$0" "" "Firefox URL" 0
${WriteRegStr2} $TmpVal "$0" "FriendlyTypeName" "Firefox URL" 0
${WriteRegStr2} $TmpVal "$0" "URL Protocol" "" 0
${WriteRegDWORD2} $TmpVal "$0" "EditFlags" 2 0
StrCpy $0 "Software\Classes\FirefoxURL\DefaultIcon"
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\",0"
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
StrCpy $0 "Software\Classes\FirefoxURL\shell\open\command"
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\" -url $\"%1$\""
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
StrCpy $0 "Software\Classes\FirefoxURL\shell\open\ddeexec"
StrCpy $1 "$\"%1$\",,0,0,,,,"
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
${WriteRegStr2} $TmpVal "$0" "NoActivateHandler" "" 0
StrCpy $0 "Software\Classes\FirefoxURL\shell\open\ddeexec\Application"
${WriteRegStr2} $TmpVal "$0" "" "${DDEApplication}" 0
StrCpy $0 "Software\Classes\gopher\shell\open\ddeexec\ifexec"
StrCpy $1 ",,0,0,,,,"
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
StrCpy $0 "Software\Classes\FirefoxURL\shell\open\ddeexec\Topic"
${WriteRegStr2} $TmpVal "$0" "" "WWW_OpenURL" 0
StrCpy $0 "Software\Classes\FirefoxHTML\DefaultIcon"
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\",1"
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
StrCpy $0 "Software\Classes\FirefoxHTML\shell\open\command"
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\" -url $\"%1$\""
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
StrCpy $0 "Software\Classes\FirefoxHTML\shell\open\ddeexec"
StrCpy $1 "$\"%1$\",,0,0,,,,"
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
${WriteRegStr2} $TmpVal "$0" "NoActivateHandler" "" 0
StrCpy $0 "Software\Classes\FirefoxHTML\shell\open\ddeexec\Application"
${WriteRegStr2} $TmpVal "$0" "" "${DDEApplication}" 0
StrCpy $0 "Software\Classes\gopher\shell\open\ddeexec\ifexec"
StrCpy $1 ",,0,0,,,,"
${WriteRegStr2} $TmpVal "$0" "" "$1" 0
StrCpy $0 "Software\Classes\FirefoxHTML\shell\open\ddeexec\Topic"
${WriteRegStr2} $TmpVal "$0" "" "WWW_OpenURL" 0
; Vista Registered Application
${StrFilter} "${FileMainEXE}" "+" "" "" $R9
StrCpy $0 "Software\RegisteredApplications"
StrCpy $1 "Software\Clients\StartMenuInternet\$R9\Capabilities"
${WriteRegStr2} $TmpVal "$0" "${DDEApplication}" "$1" 0
; Vista Capabilities registry keys
StrCpy $0 "Software\Clients\StartMenuInternet\$R9\Capabilities"
StrCpy $1 "$\"$INSTDIR\${FileMainEXE}$\",0"
${WriteRegStr2} $TmpVal "$0" "ApplicationDescription" "$(REG_APP_DESC)" 0
${WriteRegStr2} $TmpVal "$0" "ApplicationIcon" "$1" 0
StrCpy $0 "Software\Clients\StartMenuInternet\$R9\Capabilities\FileAssociations"
${WriteRegStr2} $TmpVal "$0" ".htm" "FirefoxHTML" 0
${WriteRegStr2} $TmpVal "$0" ".html" "FirefoxHTML" 0
${WriteRegStr2} $TmpVal "$0" ".shtml" "FirefoxHTML" 0
${WriteRegStr2} $TmpVal "$0" ".xht" "FirefoxHTML" 0
${WriteRegStr2} $TmpVal "$0" ".xhtml" "FirefoxHTML" 0
StrCpy $0 "Software\Clients\StartMenuInternet\$R9\Capabilities\StartMenu"
${WriteRegStr2} $TmpVal "$0" "StartMenuInternet" "$R9" 0
StrCpy $0 "Software\Clients\StartMenuInternet\$R9\Capabilities\URLAssociations"
${WriteRegStr2} $TmpVal "$0" "chrome" "FirefoxURL" 0
${WriteRegStr2} $TmpVal "$0" "ftp" "FirefoxURL" 0
${WriteRegStr2} $TmpVal "$0" "gopher" "FirefoxURL" 0
${WriteRegStr2} $TmpVal "$0" "http" "FirefoxURL" 0
${WriteRegStr2} $TmpVal "$0" "https" "FirefoxURL" 0
${EndIf}
; These need special handling on uninstall since they may be overwritten by
; an install into a different location.
StrCpy $0 "Software\Microsoft\Windows\CurrentVersion\App Paths\${FileMainEXE}"
${WriteRegStr2} $TmpVal "$0" "" "$INSTDIR\${FileMainEXE}" 0
${WriteRegStr2} $TmpVal "$0" "Path" "$INSTDIR" 0
StrCpy $0 "MIME\Database\Content Type\application/x-xpinstall;app=firefox"
${WriteRegStrHKCR} "HKCR" "$0" "Extension" ".xpi" 0
StrCpy $0 "Software\Classes\MIME\Database\Content Type\application/x-xpinstall;app=firefox"
${WriteRegStr2} $TmpVal "$0" "Extension" ".xpi" 0
StrCpy $0 "Software\Microsoft\MediaPlayer\ShimInclusionList\$R9"
${CreateRegKey} "$TmpVal" "$0" 0
@ -855,6 +1032,22 @@ Function leaveComponents
FunctionEnd
Function preDirectory
${IsVista} $R9
${If} $R9 == "true"
SetShellVarContext all ; Set SHCTX to HKLM
${GetExistingInstallPath} "Software\Mozilla" $R9
${If} $R9 != "false"
StrCpy $INSTDIR "$R9"
${CheckDiskSpace} $R9
${If} $R9 == "true"
${CanWriteToInstallDir} $R9
${If} $R9 == "true"
Abort
${EndIf}
${EndIf}
${EndIf}
${EndIf}
${If} $InstallType != 4
${CheckDiskSpace} $R9
${If} $R9 != "false"

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

@ -74,6 +74,7 @@ Var TmpVal
!insertmacro un.RegCleanUninstall
!insertmacro un.CloseApp
!insertmacro un.GetSecondInstallPath
!insertmacro un.IsVista
Name "${BrandFullName}"
OutFile "uninst.exe"
@ -205,6 +206,11 @@ Section "Uninstall"
${EndIf}
${EndIf}
${un.IsVista} $R9
${If} $R9 == "true"
DeleteRegValue HKLM "Software\RegisteredApplications" "${DDEApplication}"
${EndIf}
; Remove files. If we don't have a log file skip
${If} ${FileExists} "$INSTDIR\uninstall\uninstall.log"
; Copy the uninstall log file to a temporary file
@ -417,7 +423,7 @@ Function .onInit
SetShellVarContext all ; Set $DESKTOP to All Users
; Hide icons - initiated from Set Program Access and Defaults
${If} $R0 == '/ua "${AppVersion} (${AB_CD})" /hs browser'
${If} $R0 == "/HideShortcuts"
WriteRegDWORD HKLM $R1 "IconsVisible" 0
${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
SetShellVarContext current ; Set $DESKTOP to the current user's desktop
@ -450,7 +456,7 @@ Function .onInit
${EndIf}
; Show icons - initiated from Set Program Access and Defaults
${If} $R0 == '/ua "${AppVersion} (${AB_CD})" /ss browser'
${If} $R0 == "/ShowShortcuts"
WriteRegDWORD HKLM $R1 "IconsVisible" 1
${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
CreateShortCut "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0

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

@ -67,6 +67,11 @@ Exch 1 ; exchange the top of the stack with 2 below the top of the stack
Exch $R9 ; exchange the new $R9 value with the top of the stack
*/
; Modified version of the following MUI macros to support Mozilla localization.
; MUI_LANGUAGE
; MUI_LANGUAGEFILE_BEGIN
; MOZ_MUI_LANGUAGEFILE_END
; See <NSIS App Dir>/Contrib/Modern UI/System.nsh for more information
!define MUI_INSTALLOPTIONS_READ "!insertmacro MUI_INSTALLOPTIONS_READ"
!macro MOZ_MUI_LANGUAGE LANGUAGE
@ -525,6 +530,87 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
!verbose pop
!macroend
/**
* Checks whether the system is running Vista. If the system is running Vista
* this will return true... if not, this will return false.
*
* IMPORTANT! $R9 will be overwritten by this macro with the return value so
* protect yourself!
*
* @return _RESULT
* true if the system is running Vista otherwise false.
*
* $R7 = value of CurrentVersion from call to ReadRegStr
* $R8 = leftmost char from $R7 used for comparison. If this is 6 then the
* system is running Vista.
* $R9 = _RESULT
*/
!macro IsVista
!ifndef ${_MOZFUNC_UN}IsVista
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!define ${_MOZFUNC_UN}IsVista "!insertmacro ${_MOZFUNC_UN}IsVistaCall"
Function ${_MOZFUNC_UN}IsVista
Push $R7
Push $R8
StrCpy $R9 "false"
ClearErrors
ReadRegStr $R7 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
IfErrors end 0
StrCpy $R8 $R7 1
StrCmp $R8 "6" 0 end
StrCpy $R9 "true"
end:
ClearErrors
Pop $R8
Pop $R7
Push $R9
FunctionEnd
!verbose pop
!endif
!macroend
!macro IsVistaCall _RESULT
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Call IsVista
Pop ${_RESULT}
!verbose pop
!macroend
!macro un.IsVistaCall _RESULT
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Call un.IsVista
Pop ${_RESULT}
!verbose pop
!macroend
!macro un.IsVista
!ifndef un.IsVista
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!undef _MOZFUNC_UN
!define _MOZFUNC_UN "un."
!insertmacro IsVista
!undef _MOZFUNC_UN
!define _MOZFUNC_UN
!verbose pop
!endif
!macroend
/**
* Checks whether we can write to the install directory. If the install
* directory already exists this will attempt to create a temporary file in the
@ -550,8 +636,8 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
!define ${_MOZFUNC_UN}CanWriteToInstallDir "!insertmacro ${_MOZFUNC_UN}CanWriteToInstallDirCall"
Function ${_MOZFUNC_UN}CanWriteToInstallDir
Push $R7
Push $R8
Push $R7
StrCpy $R9 "true"
IfFileExists "$INSTDIR" 0 checkCreateDir
@ -577,8 +663,8 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
end:
ClearErrors
Pop $R8
Pop $R7
Pop $R8
Push $R9
FunctionEnd
@ -617,7 +703,6 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
!endif
!macroend
/**
* Checks whether there is sufficient free space available on the installation
* directory's drive. If there is sufficient free space this will return true...
@ -1465,6 +1550,114 @@ Exch $R9 ; exchange the new $R9 value with the top of the stack
!endif
!macroend
/**
* Finds an installation of the application so we can force an install into an
* existing location for Vista. This uses SHCTX to determine the
* registry hive so you must call SetShellVarContext first.
*
* IMPORTANT! $R9 will be overwritten by this macro with the return value so
* protect yourself!
*
* @param _KEY
* The registry subkey (typically this will be Software\Mozilla).
* @return _RESULT
* false if an install isn't found, path to the main exe if an install
* is found.
*
* $R3 = _KEY
* $R4 = value returned from the outer loop's EnumRegKey
* $R5 = value returned from ReadRegStr
* $R6 = counter for the outer loop's EnumRegKey
* $R7 = value returned popped from the stack for GetPathFromRegStr macro
* $R8 = value returned popped from the stack for GetParentDir macro
* $R9 = _RESULT
*/
!macro GetExistingInstallPath
!ifndef ${_MOZFUNC_UN}GetExistingInstallPath
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!define ${_MOZFUNC_UN}GetExistingInstallPath "!insertmacro ${_MOZFUNC_UN}GetExistingInstallPathCall"
Function ${_MOZFUNC_UN}GetExistingInstallPath
Exch $R3
Push $R4
Push $R5
Push $R6
Push $R7
Push $R8
StrCpy $R9 "false"
StrCpy $R6 0 ; set the counter for the loop to 0
loop:
EnumRegKey $R4 SHCTX $R3 $R6
StrCmp $R4 "" end ; if empty there are no more keys to enumerate
IntOp $R6 $R6 + 1 ; increment the loop's counter
ClearErrors
ReadRegStr $R5 SHCTX "$R3\$R4\bin" "PathToExe"
IfErrors loop
Push $R5
${GetPathFromRegStr}
Pop $R7
IfFileExists "$R7" 0 +5
Push "$R7"
${GetParent} "$R7" $R8
StrCpy $R9 "$R8"
GoTo end
GoTo loop
end:
ClearErrors
Pop $R8
Pop $R7
Pop $R6
Pop $R5
Pop $R4
Exch $R3
Push $R9
FunctionEnd
!verbose pop
!endif
!macroend
!macro GetExistingInstallPathCall _KEY _RESULT
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Push "${_KEY}"
Call GetExistingInstallPath
Pop ${_RESULT}
!verbose pop
!macroend
!macro un.GetExistingInstallPathCall _KEY _RESULT
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Push "${_KEY}"
Call un.GetExistingInstallPath
Pop ${_RESULT}
!verbose pop
!macroend
!macro un.GetExistingInstallPath
!ifndef un.GetExistingInstallPath
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
!undef _MOZFUNC_UN
!define _MOZFUNC_UN "un."
!insertmacro GetExistingInstallPath
!undef _MOZFUNC_UN
!define _MOZFUNC_UN
!verbose pop
!endif
!macroend
/**
* Finds a second installation of the application so we can make informed
* decisions about registry operations. This uses SHCTX to determine the