0
Files
android_webview
apps
ash
base
build
build_overrides
buildtools
cc
chrome
chromecast
chromeos
clank
codelabs
components
content
courgette
crypto
dbus
device
docs
accessibility
autofill
chromeos
design
enterprise
experiments
fuchsia
gpu
images
infra
intl
ios
lacros
linux
login
mac
media
memory
memory-infra
patterns
privacy
privacy_budget
process
security
speed
speed_metrics
standards
telemetry_extension
testing
transcripts
ui
updater
webapps
website
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_isolated_splits.md
android_jni_ownership_best_practices.md
android_logging.md
android_native_libraries.md
android_studio.md
angle_in_chromium.md
api_keys.md
asan.md
atom.md
benchmark_performance_regressions.md
bitmap_pipeline.md
branch_gardener.md
building_old_revisions.md
callback.md
ccache_mac.md
chrome_browser_design_principles.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
cipd_and_3pp.md
cl_respect.md
cl_tips.md
clang.md
clang_code_coverage_wrapper.md
clang_format.md
clang_gardening.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
cq_fault_attribution.md
cr_respect.md
cr_user_manual.md
cross_platform_ui.md
cygwin_dll_remapping_failure.md
dangling_ptr.md
dangling_ptr_guide.md
dbus_mojo_connection_service.md
debugging_with_crash_keys.md
dependencies.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_guarding_guidelines.md
flag_ownership.md
frame_trees.md
gardener.md
gcs_dependencies.md
gdbinit.md
get_the_code.md
git_cookbook.md
git_submodules.md
git_tips.md
google_chrome_branded_builds.md
google_play_services.md
graphical_debugging_aid_chromium_views.md
gwp_asan.md
history_manipulation_intervention.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
life_of_a_frame.md
lldbinit.md
mac_arm64.md
mac_build_instructions.md
mac_lld.md
modifying_session_history_serialization.md
mojo_and_services.md
mojo_ipc_conversion.md
mojo_testing.md
native_relocations.md
navbar.md
navigation-request-navigation-state.gv
navigation-request-navigation-state.png
navigation.md
navigation_concepts.md
network_traffic_annotations.md
no_sources_assignment_filter.md
optimizing_web_uis.md
orderfile.md
origin_trials_integration.md
ozone_overview.md
parsing_test_results.md
pgo.md
piranha_plant.md
process_model_and_site_isolation.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
rust-unsafe.md
rust.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
testing_webui.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
unretained_dangling_ptr_guide.md
unsafe_buffers.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_build_configuration.md
webui_code_sharing.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_web
gin
google_apis
google_update
gpu
headless
infra
internal
ios
ios_internal
ipc
media
mojo
native_client
native_client_sdk
net
pdf
ppapi
printing
remoting
rlz
sandbox
services
signing_keys
skia
sql
storage
styleguide
testing
third_party
tools
ui
url
v8
webkit
.clang-format
.clang-tidy
.clangd
.eslintrc.js
.git-blame-ignore-revs
.gitallowed
.gitattributes
.gitignore
.gitmodules
.gn
.mailmap
.rustfmt.toml
.vpython3
.yapfignore
ATL_OWNERS
AUTHORS
BUILD.gn
CODE_OF_CONDUCT.md
CPPLINT.cfg
DEPS
DIR_METADATA
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
Fabrice de Gans 027bd31ec4 [code-health] Update shortcut_properties.py for python3
Bug: 941669
Change-Id: I204abfe771e2e8d143d698f45df09d3c4c990d48
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3892284
Auto-Submit: Fabrice de Gans <fdegans@chromium.org>
Commit-Queue: Greg Thompson <grt@chromium.org>
Reviewed-by: Greg Thompson <grt@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1046294}
2022-09-13 10:17:21 +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:

vpython3 \src\chromium\src\chrome\installer\tools\shortcut_properties.py \
    --dump-all \
    "%APPDATA%\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.