0
Files
android_webview
apps
ash
base
build
build_overrides
buildtools
cc
chrome
chromecast
chromeos
cloud_print
codelabs
components
content
courgette
crypto
dbus
device
docs
accessibility
autofill
design
enterprise
fuchsia
gpu
images
infra
ios
linux
login
mac
media
memory
memory-infra
patterns
privacy
privacy_budget
process
security
speed
speed_metrics
sync
testing
ui
updater
workflow
DIR_METADATA
OWNERS
README.md
accessibility.md
ad_tagging.md
adding_to_third_party.md
android_accessing_cpp_enums_in_java.md
android_accessing_cpp_features_in_java.md
android_accessing_cpp_switches_in_java.md
android_build_instructions.md
android_cast_build_instructions.md
android_debugging_instructions.md
android_dynamic_feature_modules.md
android_emulator.md
android_logging.md
android_native_libraries.md
android_studio.md
angle_in_chromium.md
asan.md
atom.md
bitmap_pipeline.md
branch_sheriff.md
building_old_revisions.md
callback.md
ccache_mac.md
chrome_os_logging.md
chrome_settings.md
chrome_untrusted.md
chromedriver_status.md
chromeos_build_instructions.md
chromeos_glossary.md
chromium_browser_vs_google_chrome.md
chromoting_android_hacking.md
cipd_and_3pp.md
cl_respect.md
clang.md
clang_code_coverage_wrapper.md
clang_format.md
clang_sheriffing.md
clang_static_analyzer.md
clang_tidy.md
clang_tool_refactoring.md
clangd.md
clion.md
closure_compilation.md
cocoa_tips_and_tricks.md
code_review_owners.md
code_reviews.md
commit_checklist.md
component_build.md
configuration.md
contributing.md
cr_respect.md
cr_user_manual.md
cross_platform_ui.md
cygwin_dll_remapping_failure.md
dbus_mojo_connection_service.md
debugging_with_crash_keys.md
deterministic_builds.md
disassemble_code.md
documentation_best_practices.md
documentation_guidelines.md
early-hints.md
eclipse.md
emacs.md
erc_irc.md
flag_expiry.md
flag_ownership.md
gdbinit.md
get_the_code.md
git_cookbook.md
git_tips.md
google_chrome_branded_builds.md
google_play_services.md
graphical_debugging_aid_chromium_views.md
gwp_asan.md
how_cc_works.md
how_to_add_your_feature_flag.md
how_to_extend_web_test_framework.md
idn.md
initialize_blink_features.md
inlined_stack_traces.md
installation_at_vmware.md
ios_build_instructions.md
ios_infra.md
ios_voiceover.md
kiosk_mode.md
lacros.md
lldbinit.md
luci_migration_faq.md
mac_arm64.md
mac_build_instructions.md
mac_lld.md
mojo_and_services.md
mojo_ipc_conversion.md
native_relocations.md
navigation-request-navigation-state.gv
navigation-request-navigation-state.png
navigation.md
navigation_concepts.md
network_traffic_annotations.md
new_port_policy.md
no_sources_assignment_filter.md
old_chromoting_build_instructions.md
optimizing_web_uis.md
optional.md
origin_trials_integration.md
ozone_overview.md
parsing_test_results.md
pgo.md
piranha_plant.md
profiling.md
profiling_content_shell_on_android.md
proxy_auto_config.md
qtcreator.md
release_branch_guidance.md
render-frame-host-lifecycle-state.gv
render-frame-host-lifecycle-state.png
render_document.md
seccomp_sandbox_crash_dumping.md
servicification.md
session_history.md
sheriff.md
shutdown.md
special_case_urls.md
static_initializers.md
sublime_ide.md
system_hardening_features.md
tab_helpers.md
threading_and_tasks.md
threading_and_tasks_faq.md
threading_and_tasks_testing.md
toolchain_support.md
tour_of_luci_ui.md
tpm_quick_ref.md
translation_screenshots.md
trusted_types_on_webui.md
updating_clang.md
updating_clang_format_binaries.md
use_counter_wiki.md
useful_urls.md
user_data_dir.md
user_data_storage.md
user_handle_mapping.md
vanilla_msysgit_workflow.md
vscode.md
vscode_python.md
webui_explainer.md
webui_in_chrome.md
webui_in_components.md
webview_policies.md
win_cross.md
win_order_files.md
windows_build_instructions.md
windows_native_window_occlusion_tracking.md
windows_pwa_integration.md
windows_shortcut_and_taskbar_handling.md
windows_split_dll.md
windows_virtual_desktop_handling.md
wmax_tokens.md
working_remotely_with_android.md
writing_clang_plugins.md
extensions
fuchsia
gin
google_apis
google_update
gpu
headless
infra
ios
ipc
jingle
media
mojo
native_client_sdk
net
pdf
ppapi
printing
remoting
rlz
sandbox
services
skia
sql
storage
styleguide
testing
third_party
tools
ui
url
weblayer
.clang-format
.clang-tidy
.eslintrc.js
.git-blame-ignore-revs
.gitattributes
.gitignore
.gn
.vpython
.vpython3
.yapfignore
AUTHORS
BUILD.gn
CODE_OF_CONDUCT.md
DEPS
DIR_METADATA
ENG_REVIEW_OWNERS
LICENSE
LICENSE.chromium_os
OWNERS
PRESUBMIT.py
PRESUBMIT_test.py
PRESUBMIT_test_mocks.py
README.md
WATCHLISTS
codereview.settings
src/docs/windows_shortcut_and_taskbar_handling.md
David Bienvenu 96bd9fd49c Add .md for Windows Shortcut and taskbar handling
Change-Id: I18d23eb64d576ea1e9ff443f2de7b9c0c03da81f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2448664
Commit-Queue: David Bienvenu <davidbienvenu@chromium.org>
Reviewed-by: Jesse McKenna <jessemckenna@google.com>
Cr-Commit-Position: refs/heads/master@{#813866}
2020-10-05 20:02:22 +00:00

4.3 KiB

Windows Shortcut and Pinned Taskbar Icon handling

When Chrome is installed on Windows, it creates a shortcut on the desktop that launches Chrome. It also adds the same shortcut to the start menu. These shortcuts do not specify a profile, so they launch Chrome with the most recently used profile.

Windows allows users to pin applications to the taskbar. When a user pins an application to the taskbar, Windows looks for a desktop shortcut that matches the application, and if it finds one, it creates a .lnk file in the directory <user dir>\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar. If it does not find a matching desktop shortcut, it creates an 8-hex-digit sub-directory of <user dir>\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\ImplicitAppShortcuts\ and puts the .lnk file in that directory. For example, 3ffff1b1b170b31e.

App windows on Windows have an App User Model ID (AUMI) property. For Chrome windows, this is set in BrowserWindowPropertyManager::UpdateWindowProperties, when a window is opened. Windows desktop shortcuts have an app model property, and this should match the open window's AUMI. Windows groups open windows with the same AUMI to a taskbar icon.

There are two kinds of Chrome windows with AUMI's: browser windows, and app windows, which include web apps, and extensions, i.e., windows opened via --app-id or --app.

GetAppUserModelIdForBrowser constructs an AUMI for a browser window and GetAppUserModelIdForApp constructs an AUMI for an app window. Each calls ShellUtil::BuildAppUserModelId to construct the AUMI out of component strings.

All AUMI's start with the base app id, install_static::GetBaseAppId. This varies for different Chrome channels (e.g., Canary vs. Stable) and different Chromium-based browsers (e.g., Chrome vs. Chromium).

The AUMI for a browser app has the format: <BaseAppId>.<app_name>[.<profile_name>]. profile_name is only appended when it's not the default profile.

The AUMI for a Chrome browser window has the format: <BaseAppId>[browser_suffix][.profile_name]. profile_name is only appended when it's not the default profile. browser_suffix is only appended to the BaseAppId if the installer has set the kRegisterChromeBrowserSuffix command line switch, e.g., on user-level installs.

Since AUMI's for browser and app windows include the profile_name, each profile's windows will be grouped together on the taskbar.

shell_integration_win.cc has a function GetExpectedAppId to determine what the AUMI for a shortcut should be. It also has a function MigrateTaskbarPins to migrate pinned taskbar icons if the AUMI's need to change.

Multi-profile Support

When the user has more than one profile, the shortcuts are renamed to include the profile name, e.g., Chrome.lnk becomes <profile name> - Chrome. The shortcut icons, both desktop and taskbar, are badged with their profile icon. This badged icon is also used in the tab preview for a Chrome window.

Diagnosing Issues

To dump a taskbar icon's properties, run this command:

python \src\chromium\src\chrome\installer\tools\shortcut_properties.py --dump-all <user dir>\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch\User Pinned\TaskBar

This shows you the properties of all the taskbar pinned icons. If the taskbar icon is in a subdirectory of ImplicitApps, pass that directory to shortcut_properties.py.