Bug 661363 - Port bug 562753 (On upgrade, old win7 taskbar entries should have their app model id upgraded, based on install path) to Thunderbird. r=Standard8, sr=bienvenu
This commit is contained in:
Родитель
8f79905e29
Коммит
227725ff37
|
@ -46,6 +46,8 @@
|
|||
#include "nsILocalFile.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsIWinTaskbar.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
||||
#ifdef _WIN32_WINNT
|
||||
#undef _WIN32_WINNT
|
||||
|
@ -63,7 +65,9 @@
|
|||
#define REG_FAILED(val) \
|
||||
(val != ERROR_SUCCESS)
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsWindowsShellService, nsIShellService)
|
||||
#define NS_TASKBAR_CONTRACTID "@mozilla.org/windows-taskbar;1"
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsWindowsShellService, nsIWindowsShellService, nsIShellService)
|
||||
|
||||
static nsresult
|
||||
OpenKeyForReading(HKEY aKeyRoot, const nsAString& aKeyName, HKEY* aKey)
|
||||
|
@ -139,6 +143,126 @@ static SETTING gFeedSettings[] = {
|
|||
{ MAKE_KEY_NAME1("feed", SOP), "", VAL_MAIL_OPEN, APP_PATH_SUBSTITUTION },
|
||||
};
|
||||
|
||||
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->Append(NS_LITERAL_STRING("uninstall"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = appHelper->Append(NS_LITERAL_STRING("helper.exe"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return appHelper->GetPath(aPath);
|
||||
}
|
||||
|
||||
nsresult
|
||||
LaunchHelper(nsAutoString& aPath, nsAutoString& aParams)
|
||||
{
|
||||
SHELLEXECUTEINFOW executeInfo = {0};
|
||||
|
||||
executeInfo.cbSize = sizeof(SHELLEXECUTEINFOW);
|
||||
executeInfo.hwnd = NULL;
|
||||
executeInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
|
||||
executeInfo.lpDirectory = NULL;
|
||||
executeInfo.lpFile = aPath.get();
|
||||
executeInfo.lpParameters = aParams.get();
|
||||
executeInfo.nShow = SW_SHOWNORMAL;
|
||||
|
||||
if (ShellExecuteExW(&executeInfo))
|
||||
// Block until the program exits
|
||||
WaitForSingleObject(executeInfo.hProcess, INFINITE);
|
||||
else
|
||||
return NS_ERROR_ABORT;
|
||||
|
||||
// We're going to ignore errors here since there's nothing we can do about
|
||||
// them, and helper.exe seems to return non-zero ret on success.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowsShellService::ShortcutMaintenance()
|
||||
{
|
||||
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, "mail.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;
|
||||
|
||||
nsAutoString params;
|
||||
params.AssignLiteral(" /UpdateShortcutAppUserModelIds");
|
||||
return LaunchHelper(appHelperPath, params);
|
||||
}
|
||||
|
||||
nsresult nsWindowsShellService::Init()
|
||||
{
|
||||
nsresult rv;
|
||||
|
@ -202,24 +326,9 @@ nsWindowsShellService::IsDefaultClient(PRBool aStartupCheck, PRUint16 aApps, PRB
|
|||
NS_IMETHODIMP
|
||||
nsWindowsShellService::SetDefaultClient(PRBool aForAllUsers, PRUint16 aApps)
|
||||
{
|
||||
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;
|
||||
|
||||
nsAutoString params;
|
||||
if (aForAllUsers)
|
||||
|
@ -236,25 +345,7 @@ nsWindowsShellService::SetDefaultClient(PRBool aForAllUsers, PRUint16 aApps)
|
|||
params.AppendLiteral(" News");
|
||||
}
|
||||
|
||||
SHELLEXECUTEINFOW executeInfo = {0};
|
||||
|
||||
executeInfo.cbSize = sizeof(SHELLEXECUTEINFOW);
|
||||
executeInfo.hwnd = NULL;
|
||||
executeInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
|
||||
executeInfo.lpDirectory = NULL;
|
||||
executeInfo.lpFile = appHelperPath.get();
|
||||
executeInfo.lpParameters = params.get();
|
||||
executeInfo.nShow = SW_SHOWNORMAL;
|
||||
|
||||
if (ShellExecuteExW(&executeInfo))
|
||||
// Block until the program exits
|
||||
WaitForSingleObject(executeInfo.hProcess, INFINITE);
|
||||
else
|
||||
return NS_ERROR_ABORT;
|
||||
|
||||
// We're going to ignore errors here since there's nothing we can do about
|
||||
// them, and helper.exe seems to return non-zero ret on success.
|
||||
return NS_OK;
|
||||
return LaunchHelper(appHelperPath, params);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#ifndef nsMailWinIntegration_h_
|
||||
#define nsMailWinIntegration_h_
|
||||
|
||||
#include "nsIShellService.h"
|
||||
#include "nsIWindowsShellService.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsString.h"
|
||||
|
||||
|
@ -56,7 +56,7 @@ typedef struct {
|
|||
PRInt32 flags;
|
||||
} SETTING;
|
||||
|
||||
class nsWindowsShellService : public nsIShellService
|
||||
class nsWindowsShellService : public nsIWindowsShellService
|
||||
{
|
||||
public:
|
||||
nsWindowsShellService();
|
||||
|
@ -65,6 +65,7 @@ public:
|
|||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISHELLSERVICE
|
||||
NS_DECL_NSIWINDOWSSHELLSERVICE
|
||||
|
||||
protected:
|
||||
PRBool TestForDefault(SETTING aSettings[], PRInt32 aSize);
|
||||
|
|
|
@ -45,6 +45,6 @@ include $(DEPTH)/config/autoconf.mk
|
|||
MODULE = shellservice
|
||||
XPIDL_MODULE = shellservice
|
||||
|
||||
XPIDLSRCS = nsIShellService.idl
|
||||
XPIDLSRCS = nsIShellService.idl nsIWindowsShellService.idl
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Shell Service.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Siddharth Agarwal <sid.bugzilla@gmail.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
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIShellService.idl"
|
||||
|
||||
[scriptable, uuid(c6bcecde-6f2e-417c-bc30-466f560c3b51)]
|
||||
interface nsIWindowsShellService : nsIShellService
|
||||
{
|
||||
/**
|
||||
* Perform some Windows 7+ shortcut maintenance. This is called at program startup.
|
||||
*/
|
||||
void shortcutMaintenance();
|
||||
};
|
|
@ -61,6 +61,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "_taskbarService",
|
|||
"@mozilla.org/windows-taskbar;1",
|
||||
"nsIWinTaskbar");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "_winShellService",
|
||||
"@mozilla.org/mail/shell-service;1",
|
||||
"nsIWindowsShellService");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "_prefs", function() {
|
||||
return Services.prefs.getBranch(PREF_TASKBAR_BRANCH)
|
||||
.QueryInterface(Ci.nsIPrefBranch2);
|
||||
|
@ -103,6 +107,16 @@ let 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.
|
||||
try {
|
||||
// dev builds may not have helper.exe, ignore failures.
|
||||
this._shortcutMaintenance();
|
||||
}
|
||||
catch (ex) {
|
||||
}
|
||||
|
||||
// Store our task list config data
|
||||
this._tasks = gTasks;
|
||||
|
||||
|
@ -130,6 +144,10 @@ let WinTaskbarJumpList = {
|
|||
this._free();
|
||||
},
|
||||
|
||||
_shortcutMaintenance: function WTBJL__maintenace() {
|
||||
_winShellService.shortcutMaintenance();
|
||||
},
|
||||
|
||||
/**
|
||||
* List building
|
||||
*/
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
# Note - Thunderbird does not set a Vendor in application.ini!
|
||||
!define AppName "Thunderbird"
|
||||
!define AppVersion "@MOZ_APP_VERSION@"
|
||||
!define AppUserModelID "${AppName}.${AppVersion}"
|
||||
# The app vendor is blank, and the way app model IDs are formed is with
|
||||
# vendor.name.version.
|
||||
!define AppUserModelID ".${AppName}.${AppVersion}"
|
||||
!define GREVersion @MOZILLA_VERSION@
|
||||
!define AB_CD "@AB_CD@"
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@ VIAddVersionKey "OriginalFilename" "setup.exe"
|
|||
!insertmacro RegCleanMain
|
||||
!insertmacro RegCleanUninstall
|
||||
!insertmacro SetBrandNameVars
|
||||
!insertmacro UpdateShortcutAppModelIDs
|
||||
!insertmacro UnloadUAC
|
||||
!insertmacro WriteRegStr2
|
||||
!insertmacro WriteRegDWORD2
|
||||
|
@ -401,6 +402,29 @@ Section "-Application" APP_IDX
|
|||
${LogQuickLaunchShortcut} "${BrandFullName}.lnk"
|
||||
${LogDesktopShortcut} "${BrandFullName}.lnk"
|
||||
|
||||
; Best effort to update the Win7 taskbar and start menu shortcut app model
|
||||
; id's. The possible contexts are current user / system and the user that
|
||||
; elevated the installer.
|
||||
Call FixShortcutAppModelIDs
|
||||
; If the current context is all also perform Win7 taskbar and start menu link
|
||||
; maintenance for the current user context.
|
||||
${If} $TmpVal == "HKLM"
|
||||
SetShellVarContext current ; Set SHCTX to HKCU
|
||||
Call FixShortcutAppModelIDs
|
||||
SetShellVarContext all ; Set SHCTX to HKLM
|
||||
${EndIf}
|
||||
|
||||
; If running elevated also perform Win7 taskbar and start menu link
|
||||
; maintenance for the unelevated user context in case that is different than
|
||||
; the current user.
|
||||
ClearErrors
|
||||
${GetParameters} $0
|
||||
${GetOptions} "$0" "/UAC:" $0
|
||||
${Unless} ${Errors}
|
||||
GetFunctionAddress $0 FixShortcutAppModelIDs
|
||||
UAC::ExecCodeSegment $0
|
||||
${EndIf}
|
||||
|
||||
; UAC only allows elevating to an Admin account so there is no need to add
|
||||
; the Start Menu or Desktop shortcuts from the original unelevated process
|
||||
; since this will either add it for the user if unelevated or All Users if
|
||||
|
@ -465,6 +489,9 @@ Section "-InstallEndCleanup"
|
|||
${EndIf}
|
||||
${EndUnless}
|
||||
|
||||
; Win7 taskbar and start menu link maintenance
|
||||
Call FixShortcutAppModelIDs
|
||||
|
||||
; Refresh desktop icons
|
||||
System::Call "shell32::SHChangeNotify(i, i, i, i) v (0x08000000, 0, 0, 0)"
|
||||
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
${RegCleanMain} "Software\Mozilla"
|
||||
${RegCleanUninstall}
|
||||
${UpdateProtocolHandlers}
|
||||
; Win7 taskbar and start menu link maintenance
|
||||
Call FixShortcutAppModelIDs
|
||||
|
||||
; Upgrade the copies of the MAPI DLL's
|
||||
${UpgradeMapiDLLs}
|
||||
|
@ -70,6 +72,9 @@
|
|||
${RegCleanUninstall}
|
||||
${UpdateProtocolHandlers}
|
||||
|
||||
; Win7 taskbar and start menu link maintenance
|
||||
Call FixShortcutAppModelIDs
|
||||
|
||||
; Only update the Clients\Mail registry key values if they don't exist or
|
||||
; this installation is the same as the one set in those keys.
|
||||
ReadRegStr $0 HKLM "Software\Clients\Mail\${ClientsRegName}\DefaultIcon" ""
|
||||
|
@ -729,6 +734,11 @@
|
|||
!macroend
|
||||
!define PushFilesToCheck "!insertmacro PushFilesToCheck"
|
||||
|
||||
; Helper for updating the shortcut application model IDs.
|
||||
Function FixShortcutAppModelIDs
|
||||
${UpdateShortcutAppModelIDs} "$INSTDIR\${FileMainEXE}" "${AppUserModelID}" $0
|
||||
FunctionEnd
|
||||
|
||||
; The !ifdef NO_LOG prevents warnings when compiling the installer.nsi due to
|
||||
; this function only being used by the uninstaller.nsi.
|
||||
!ifdef NO_LOG
|
||||
|
|
Загрузка…
Ссылка в новой задаче