Bug 562753 - On upgrade, update AppUserModelID for application shortcuts. r=rstrong.

This commit is contained in:
Jim Mathies 2010-05-14 19:24:50 -05:00
Родитель 32c9287d61
Коммит 80aa8025c6
7 изменённых файлов: 268 добавлений и 29 удалений

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

@ -20,6 +20,7 @@
* *
* Contributor(s): * Contributor(s):
* Ben Goodger <ben@mozilla.org> (Original Author) * Ben Goodger <ben@mozilla.org> (Original Author)
* Jim Mathies <jmathies@mozilla.com>
* *
* Alternatively, the contents of this file may be used under the terms of * Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or * either the GNU General Public License Version 2 or later (the "GPL"), or
@ -37,7 +38,7 @@
#include "nsIShellService.idl" #include "nsIShellService.idl"
[scriptable, uuid(3ee25e62-ad0f-464e-8225-c3b774137387)] [scriptable, uuid(16e7e8da-8bef-4f41-be5f-045b2e9918e1)]
interface nsIWindowsShellService : nsIShellService interface nsIWindowsShellService : nsIShellService
{ {
/** /**
@ -46,5 +47,11 @@ interface nsIWindowsShellService : nsIShellService
* @return The number of unread (new) mail messages for the current user. * @return The number of unread (new) mail messages for the current user.
*/ */
readonly attribute unsigned long unreadMailCount; readonly attribute unsigned long unreadMailCount;
/**
* Provides the shell service an opportunity to do some Win7+ shortcut
* maintenance needed on initial startup of the browser.
*/
void shortcutMaintenance();
}; };

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

@ -27,6 +27,7 @@
* Asaf Romano <mano@mozilla.com> * Asaf Romano <mano@mozilla.com>
* Ryan Jones <sciguyryan@gmail.com> * Ryan Jones <sciguyryan@gmail.com>
* Paul O'Shannessy <paul@oshannessy.com> * Paul O'Shannessy <paul@oshannessy.com>
* Jim Mathies <jmathies@mozilla.com>
* *
* Alternatively, the contents of this file may be used under the terms of * Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or * either the GNU General Public License Version 2 or later (the "GPL"), or
@ -63,6 +64,8 @@
#include "nsDirectoryServiceDefs.h" #include "nsDirectoryServiceDefs.h"
#include "nsIWindowsRegKey.h" #include "nsIWindowsRegKey.h"
#include "nsUnicharUtils.h" #include "nsUnicharUtils.h"
#include "nsIWinTaskbar.h"
#include "nsISupportsPrimitives.h"
#include "windows.h" #include "windows.h"
#include "shellapi.h" #include "shellapi.h"
@ -86,6 +89,8 @@
#define REG_FAILED(val) \ #define REG_FAILED(val) \
(val != ERROR_SUCCESS) (val != ERROR_SUCCESS)
#define NS_TASKBAR_CONTRACTID "@mozilla.org/windows-taskbar;1"
#ifndef WINCE #ifndef WINCE
NS_IMPL_ISUPPORTS2(nsWindowsShellService, nsIWindowsShellService, nsIShellService) NS_IMPL_ISUPPORTS2(nsWindowsShellService, nsIWindowsShellService, nsIShellService)
#else #else
@ -268,6 +273,127 @@ static SETTING gSettings[] = {
{ MAKE_KEY_NAME1("HTTPS", SOP), "", VAL_OPEN } { MAKE_KEY_NAME1("HTTPS", SOP), "", VAL_OPEN }
}; };
#if !defined(WINCE)
nsresult
GetHelperPath(nsAutoString& aPath)
{
nsresult rv;
nsCOMPtr<nsIProperties> directoryService =
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsILocalFile> appHelper;
rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR,
NS_GET_IID(nsILocalFile),
getter_AddRefs(appHelper));
NS_ENSURE_SUCCESS(rv, rv);
rv = appHelper->AppendNative(NS_LITERAL_CSTRING("uninstall"));
NS_ENSURE_SUCCESS(rv, rv);
rv = appHelper->AppendNative(NS_LITERAL_CSTRING("helper.exe"));
NS_ENSURE_SUCCESS(rv, rv);
return appHelper->GetPath(aPath);
}
nsresult
LaunchHelper(nsAutoString& aPath)
{
STARTUPINFOW si = {sizeof(si), 0};
PROCESS_INFORMATION pi = {0};
BOOL ok = CreateProcessW(NULL, (LPWSTR)aPath.get(), NULL, NULL,
FALSE, 0, NULL, NULL, &si, &pi);
if (!ok)
return NS_ERROR_FAILURE;
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return NS_OK;
}
#endif // !defined(WINCE)
NS_IMETHODIMP
nsWindowsShellService::ShortcutMaintenance()
{
#if !defined(WINCE)
nsresult rv;
// Launch helper.exe so it can update the application user model ids on
// shortcuts in the user's taskbar and start menu. This keeps older pinned
// shortcuts grouped correctly after major updates. Note, we also do this
// through the upgrade installer script, however, this is the only place we
// have a chance to trap links created by users who do control the install/
// update process of the browser.
nsCOMPtr<nsIWinTaskbar> taskbarInfo =
do_GetService(NS_TASKBAR_CONTRACTID);
if (!taskbarInfo) // If we haven't built with win7 sdk features, this fails.
return NS_OK;
// Avoid if this isn't Win7+
PRBool isSupported = PR_FALSE;
taskbarInfo->GetAvailable(&isSupported);
if (!isSupported)
return NS_OK;
nsAutoString appId;
if (NS_FAILED(taskbarInfo->GetDefaultGroupId(appId)))
return NS_ERROR_UNEXPECTED;
NS_NAMED_LITERAL_CSTRING(prefName, "browser.taskbar.lastgroupid");
nsCOMPtr<nsIPrefService> prefs =
do_GetService(NS_PREFSERVICE_CONTRACTID);
if (!prefs)
return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIPrefBranch> prefBranch;
prefs->GetBranch(nsnull, getter_AddRefs(prefBranch));
if (!prefBranch)
return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsISupportsString> prefString;
rv = prefBranch->GetComplexValue(prefName.get(),
NS_GET_IID(nsISupportsString),
getter_AddRefs(prefString));
if (NS_SUCCEEDED(rv)) {
nsAutoString version;
prefString->GetData(version);
if (!version.IsEmpty() && version.Equals(appId)) {
// We're all good, get out of here.
return NS_OK;
}
}
// Update the version in prefs
prefString =
do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
if (NS_FAILED(rv))
return rv;
prefString->SetData(appId);
rv = prefBranch->SetComplexValue(prefName.get(),
NS_GET_IID(nsISupportsString),
prefString);
if (NS_FAILED(rv)) {
NS_WARNING("Couldn't set last user model id!");
return NS_ERROR_UNEXPECTED;
}
nsAutoString appHelperPath;
if (NS_FAILED(GetHelperPath(appHelperPath)))
return NS_ERROR_UNEXPECTED;
appHelperPath.AppendLiteral(" /UpdateShortcutAppUserModelIds");
return LaunchHelper(appHelperPath);
#else
NS_NOTREACHED("ShortcutMaintenance not implemented on wince!");
return NS_OK;
#endif // !defined(WINCE)
}
#ifndef WINCE #ifndef WINCE
PRBool PRBool
nsWindowsShellService::IsDefaultBrowserVista(PRBool* aIsDefaultBrowser) nsWindowsShellService::IsDefaultBrowserVista(PRBool* aIsDefaultBrowser)
@ -366,24 +492,9 @@ NS_IMETHODIMP
nsWindowsShellService::SetDefaultBrowser(PRBool aClaimAllTypes, PRBool aForAllUsers) nsWindowsShellService::SetDefaultBrowser(PRBool aClaimAllTypes, PRBool aForAllUsers)
{ {
#ifndef WINCE #ifndef WINCE
nsresult rv;
nsCOMPtr<nsIProperties> directoryService =
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsILocalFile> appHelper;
rv = directoryService->Get(NS_XPCOM_CURRENT_PROCESS_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(appHelper));
NS_ENSURE_SUCCESS(rv, rv);
rv = appHelper->AppendNative(NS_LITERAL_CSTRING("uninstall"));
NS_ENSURE_SUCCESS(rv, rv);
rv = appHelper->AppendNative(NS_LITERAL_CSTRING("helper.exe"));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString appHelperPath; nsAutoString appHelperPath;
rv = appHelper->GetPath(appHelperPath); if (NS_FAILED(GetHelperPath(appHelperPath)))
NS_ENSURE_SUCCESS(rv, rv); return NS_ERROR_FAILURE;
if (aForAllUsers) { if (aForAllUsers) {
appHelperPath.AppendLiteral(" /SetAsDefaultAppGlobal"); appHelperPath.AppendLiteral(" /SetAsDefaultAppGlobal");
@ -391,17 +502,7 @@ nsWindowsShellService::SetDefaultBrowser(PRBool aClaimAllTypes, PRBool aForAllUs
appHelperPath.AppendLiteral(" /SetAsDefaultAppUser"); appHelperPath.AppendLiteral(" /SetAsDefaultAppUser");
} }
STARTUPINFOW si = {sizeof(si), 0}; return LaunchHelper(appHelperPath);
PROCESS_INFORMATION pi = {0};
BOOL ok = CreateProcessW(NULL, (LPWSTR)appHelperPath.get(), NULL, NULL,
FALSE, 0, NULL, NULL, &si, &pi);
if (!ok)
return NS_ERROR_FAILURE;
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
#else #else
SETTING* settings; SETTING* settings;
SETTING* end = gSettings + sizeof(gSettings)/sizeof(SETTING); SETTING* end = gSettings + sizeof(gSettings)/sizeof(SETTING);

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

@ -101,6 +101,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "_ioService",
"@mozilla.org/network/io-service;1", "@mozilla.org/network/io-service;1",
"nsIIOService"); "nsIIOService");
XPCOMUtils.defineLazyServiceGetter(this, "_winShellService",
"@mozilla.org/browser/shell-service;1",
"nsIWindowsShellService");
/** /**
* Global functions * Global functions
*/ */
@ -163,6 +167,11 @@ var WinTaskbarJumpList =
if (!this._initTaskbar()) if (!this._initTaskbar())
return; return;
// Win shell shortcut maintenance. If we've gone through an update,
// this will update any pinned taskbar shortcuts. Not specific to
// jump lists, but this was a convienent place to call it.
this._shortcutMaintenance();
// Store our task list config data // Store our task list config data
this._tasks = tasksCfg; this._tasks = tasksCfg;
@ -200,6 +209,10 @@ var WinTaskbarJumpList =
this._free(); this._free();
}, },
_shortcutMaintenance: function WTBJL__maintenace() {
_winShellService.shortcutMaintenance();
},
/** /**
* List building * List building
*/ */

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

@ -119,6 +119,7 @@ VIAddVersionKey "OriginalFilename" "setup.exe"
!insertmacro RegCleanMain !insertmacro RegCleanMain
!insertmacro RegCleanUninstall !insertmacro RegCleanUninstall
!insertmacro SetBrandNameVars !insertmacro SetBrandNameVars
!insertmacro UpdateShortcutAppModelIDs
!insertmacro UnloadUAC !insertmacro UnloadUAC
!insertmacro WriteRegStr2 !insertmacro WriteRegStr2
!insertmacro WriteRegDWORD2 !insertmacro WriteRegDWORD2
@ -486,6 +487,9 @@ Section "-InstallEndCleanup"
${LogHeader} "Updating Uninstall Log With Previous Uninstall Log" ${LogHeader} "Updating Uninstall Log With Previous Uninstall Log"
; Win7 taskbar and start menu link maintenance
${UpdateShortcutAppModelIDs} "$INSTDIR\${FileMainEXE}" "${AppUserModelID}"
; Refresh desktop icons ; Refresh desktop icons
System::Call "shell32::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)" System::Call "shell32::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)"

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

@ -83,6 +83,9 @@
${FixClassKeys} ${FixClassKeys}
${SetUninstallKeys} ${SetUninstallKeys}
; Win7 taskbar and start menu link maintenance
${UpdateShortcutAppModelIDs} "$INSTDIR\${FileMainEXE}" "${AppUserModelID}"
; Remove files that may be left behind by the application in the ; Remove files that may be left behind by the application in the
; VirtualStore directory. ; VirtualStore directory.
${CleanVirtualStore} ${CleanVirtualStore}

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

@ -101,6 +101,7 @@ VIAddVersionKey "OriginalFilename" "helper.exe"
!insertmacro RegCleanMain !insertmacro RegCleanMain
!insertmacro RegCleanUninstall !insertmacro RegCleanUninstall
!insertmacro SetBrandNameVars !insertmacro SetBrandNameVars
!insertmacro UpdateShortcutAppModelIDs
!insertmacro UnloadUAC !insertmacro UnloadUAC
!insertmacro WriteRegDWORD2 !insertmacro WriteRegDWORD2
!insertmacro WriteRegStr2 !insertmacro WriteRegStr2

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

@ -4675,7 +4675,15 @@
StrCmp "$R0" "" continue +1 StrCmp "$R0" "" continue +1
; Update this user's shortcuts with the latest app user model id.
ClearErrors
${GetOptions} "$R0" "/UpdateShortcutAppUserModelIds" $R2
IfErrors hideshortcuts +1
${UpdateShortcutAppModelIDs} "$INSTDIR\${FileMainEXE}" "${AppUserModelID}"
GoTo finish
; Require elevation if the user can elevate ; Require elevation if the user can elevate
hideshortcuts:
ClearErrors ClearErrors
${GetOptions} "$R0" "/HideShortcuts" $R2 ${GetOptions} "$R0" "/HideShortcuts" $R2
IfErrors showshortcuts +1 IfErrors showshortcuts +1
@ -5780,3 +5788,105 @@
${DeleteFile} "$INSTDIR\uninstall\${SHORTCUTS_LOG}" ${DeleteFile} "$INSTDIR\uninstall\${SHORTCUTS_LOG}"
!macroend !macroend
!define DeleteShortcutsLogFile "!insertmacro DeleteShortcutsLogFile" !define DeleteShortcutsLogFile "!insertmacro DeleteShortcutsLogFile"
################################################################################
# Macros for managing Win7 install features
/**
* Update Start Menu and Taskbar lnk files that point to the current install
* with the current application user model ID. Requires ApplicationID.
*
* @param _INSTALL_PATH
* The install path of the app
* @param _APP_ID
* The application user model ID for the current install
*/
!macro UpdateShortcutAppModelIDs
!ifndef UpdateShortcutAppModelIDs
!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
Exch $R8 ; stack: $R8, $R9 | $R8 = appid
Push $R7 ; stack: $R7, $R8, $R9
Push $R6
Push $R5
Push $R4 ; stack: $R4, $R5, $R6, $R7, $R8, $R9
StrCpy $R7 "$QUICKLAUNCH\User Pinned"
ClearErrors
; $R9 = install path
; $R8 = appid
; $R7 = user pinned path
; $R6 = find handle
; $R5 = found 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
${EndIf}
${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
${EndIf}
${EndIf}
ClearErrors
FindNext $R6 $R5
${Unless} ${Errors}
Goto LoopStartMenu
${EndUnless}
FindClose $R6
Pop $R4 ; stack: $R5, $R6, $R7, $R8, $R9
Pop $R5 ; stack: $R6, $R7, $R8, $R9
Pop $R6 ; stack: $R7, $R8, $R9
Pop $R7 ; stack: $R8, $R9
Exch $R8 ; stack: appid, $R9 | $R8 = old $R8
Exch 1 ; stack: $R9, appid
Exch $R9 ; stack: path, appid | $R9 = old $R9
FunctionEnd
!verbose pop
!endif
!macroend
!macro UpdateShortcutAppModelIDsCall _INSTALL_PATH _APP_ID
!verbose push
!verbose ${_MOZFUNC_VERBOSE}
Push "${_APP_ID}"
Push "${_INSTALL_PATH}"
Call UpdateShortcutAppModelIDs
!verbose pop
!macroend