Bug 562753 - On upgrade, update AppUserModelID for application shortcuts. r=rstrong.
This commit is contained in:
Родитель
4916cb4c7f
Коммит
0f30b25da0
|
@ -20,6 +20,7 @@
|
|||
*
|
||||
* Contributor(s):
|
||||
* 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
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -37,7 +38,7 @@
|
|||
|
||||
#include "nsIShellService.idl"
|
||||
|
||||
[scriptable, uuid(3ee25e62-ad0f-464e-8225-c3b774137387)]
|
||||
[scriptable, uuid(16e7e8da-8bef-4f41-be5f-045b2e9918e1)]
|
||||
interface nsIWindowsShellService : nsIShellService
|
||||
{
|
||||
/**
|
||||
|
@ -46,5 +47,11 @@ interface nsIWindowsShellService : nsIShellService
|
|||
* @return The number of unread (new) mail messages for the current user.
|
||||
*/
|
||||
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>
|
||||
* Ryan Jones <sciguyryan@gmail.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
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -63,6 +64,8 @@
|
|||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsIWindowsRegKey.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsIWinTaskbar.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
||||
#include "windows.h"
|
||||
#include "shellapi.h"
|
||||
|
@ -86,6 +89,8 @@
|
|||
#define REG_FAILED(val) \
|
||||
(val != ERROR_SUCCESS)
|
||||
|
||||
#define NS_TASKBAR_CONTRACTID "@mozilla.org/windows-taskbar;1"
|
||||
|
||||
#ifndef WINCE
|
||||
NS_IMPL_ISUPPORTS2(nsWindowsShellService, nsIWindowsShellService, nsIShellService)
|
||||
#else
|
||||
|
@ -268,6 +273,127 @@ static SETTING gSettings[] = {
|
|||
{ 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
|
||||
PRBool
|
||||
nsWindowsShellService::IsDefaultBrowserVista(PRBool* aIsDefaultBrowser)
|
||||
|
@ -366,24 +492,9 @@ NS_IMETHODIMP
|
|||
nsWindowsShellService::SetDefaultBrowser(PRBool aClaimAllTypes, PRBool aForAllUsers)
|
||||
{
|
||||
#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;
|
||||
rv = appHelper->GetPath(appHelperPath);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_FAILED(GetHelperPath(appHelperPath)))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (aForAllUsers) {
|
||||
appHelperPath.AppendLiteral(" /SetAsDefaultAppGlobal");
|
||||
|
@ -391,17 +502,7 @@ nsWindowsShellService::SetDefaultBrowser(PRBool aClaimAllTypes, PRBool aForAllUs
|
|||
appHelperPath.AppendLiteral(" /SetAsDefaultAppUser");
|
||||
}
|
||||
|
||||
STARTUPINFOW si = {sizeof(si), 0};
|
||||
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);
|
||||
return LaunchHelper(appHelperPath);
|
||||
#else
|
||||
SETTING* settings;
|
||||
SETTING* end = gSettings + sizeof(gSettings)/sizeof(SETTING);
|
||||
|
|
|
@ -101,6 +101,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "_ioService",
|
|||
"@mozilla.org/network/io-service;1",
|
||||
"nsIIOService");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "_winShellService",
|
||||
"@mozilla.org/browser/shell-service;1",
|
||||
"nsIWindowsShellService");
|
||||
|
||||
/**
|
||||
* Global functions
|
||||
*/
|
||||
|
@ -163,6 +167,11 @@ var WinTaskbarJumpList =
|
|||
if (!this._initTaskbar())
|
||||
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
|
||||
this._tasks = tasksCfg;
|
||||
|
||||
|
@ -200,6 +209,10 @@ var WinTaskbarJumpList =
|
|||
this._free();
|
||||
},
|
||||
|
||||
_shortcutMaintenance: function WTBJL__maintenace() {
|
||||
_winShellService.shortcutMaintenance();
|
||||
},
|
||||
|
||||
/**
|
||||
* List building
|
||||
*/
|
||||
|
|
|
@ -119,6 +119,7 @@ VIAddVersionKey "OriginalFilename" "setup.exe"
|
|||
!insertmacro RegCleanMain
|
||||
!insertmacro RegCleanUninstall
|
||||
!insertmacro SetBrandNameVars
|
||||
!insertmacro UpdateShortcutAppModelIDs
|
||||
!insertmacro UnloadUAC
|
||||
!insertmacro WriteRegStr2
|
||||
!insertmacro WriteRegDWORD2
|
||||
|
@ -486,6 +487,9 @@ Section "-InstallEndCleanup"
|
|||
|
||||
${LogHeader} "Updating Uninstall Log With Previous Uninstall Log"
|
||||
|
||||
; Win7 taskbar and start menu link maintenance
|
||||
${UpdateShortcutAppModelIDs} "$INSTDIR\${FileMainEXE}" "${AppUserModelID}"
|
||||
|
||||
; Refresh desktop icons
|
||||
System::Call "shell32::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)"
|
||||
|
||||
|
|
|
@ -83,6 +83,9 @@
|
|||
${FixClassKeys}
|
||||
${SetUninstallKeys}
|
||||
|
||||
; Win7 taskbar and start menu link maintenance
|
||||
${UpdateShortcutAppModelIDs} "$INSTDIR\${FileMainEXE}" "${AppUserModelID}"
|
||||
|
||||
; Remove files that may be left behind by the application in the
|
||||
; VirtualStore directory.
|
||||
${CleanVirtualStore}
|
||||
|
|
|
@ -101,6 +101,7 @@ VIAddVersionKey "OriginalFilename" "helper.exe"
|
|||
!insertmacro RegCleanMain
|
||||
!insertmacro RegCleanUninstall
|
||||
!insertmacro SetBrandNameVars
|
||||
!insertmacro UpdateShortcutAppModelIDs
|
||||
!insertmacro UnloadUAC
|
||||
!insertmacro WriteRegDWORD2
|
||||
!insertmacro WriteRegStr2
|
||||
|
|
|
@ -4675,7 +4675,15 @@
|
|||
|
||||
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
|
||||
hideshortcuts:
|
||||
ClearErrors
|
||||
${GetOptions} "$R0" "/HideShortcuts" $R2
|
||||
IfErrors showshortcuts +1
|
||||
|
@ -5780,3 +5788,105 @@
|
|||
${DeleteFile} "$INSTDIR\uninstall\${SHORTCUTS_LOG}"
|
||||
!macroend
|
||||
!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
|
||||
|
|
Загрузка…
Ссылка в новой задаче