
Change-Id: I719d6545f0ed2fc9bae19fa36cf99c1dd4308562 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2429932 Commit-Queue: David Bienvenu <davidbienvenu@chromium.org> Reviewed-by: Jesse McKenna <jessemckenna@google.com> Cr-Commit-Position: refs/heads/master@{#810414}
79 lines
4.7 KiB
Markdown
79 lines
4.7 KiB
Markdown
# Windows Progressive Web App integration
|
|
|
|
## Desktop Shortcuts
|
|
When a Progressive Web App (PWA) is installed on Windows, Chrome creates a
|
|
desktop shortcut to the PWA, with the PWA icon. The shortcut launches a small
|
|
Chrome binary chrome_proxy.exe with the app id of the PWA, and the Chrome
|
|
profile the PWA is installed in. When chrome_proxy.exe runs, it launches Chrome
|
|
with the same command line options. The shortcut links to chrome_proxy.exe
|
|
instead of chrome.exe because of
|
|
[a bug in Windows 10 start menu pinning](https://source.chromium.org/chromium/chromium/src/+/master:chrome/chrome_proxy/chrome_proxy_main_win.cc;l=23).
|
|
|
|
## File handling support
|
|
In order to make Progressive Web Apps (PWA's) more like traditional apps, PWA's
|
|
support opening files on the user's desktop. On Windows, when a PWA is
|
|
installed, if the PWA's manifest lists one or more file extension types that it
|
|
supports opening, Chrome registers the PWA as a handler for the file
|
|
extension(s), in the Windows registry. When the user right clicks on a file with
|
|
a registered extension, the PWA name and custom icon appears in the list of
|
|
applications that can open the file. The user can also set the PWA as the
|
|
default handler for the file extension.
|
|
|
|
Because of a limitation of the Windows shell, Chrome registers a per-PWA install
|
|
[launcher app](https://source.chromium.org/chromium/chromium/src/+/master:chrome/browser/web_applications/chrome_pwa_launcher/README.md;l=1)
|
|
as a handler for the file extension. Chrome ships with a canonical launcher app
|
|
called chrome_pwa_launcher.exe, which lives in the version sub-directory of the
|
|
Chrome install dir. When a PWA is installed, we create a hard link from the
|
|
PWA install dir `<profile_dir>/Web Applications/<app_id>` to the canonical launcher
|
|
app. If the hard link fails (e.g., Chrome install dir is on a different drive
|
|
than the profile dir), we copy the launcher app to the PWA install dir. In either
|
|
case, the name of the launcher app in the PWA install dir is a sanitized version
|
|
of the PWA name.
|
|
|
|
Registration starts in [web_app::RegisterFileHandlersWithOS](https://source.chromium.org/search?q=RegisterFileHandlersWithOS%20file:_win.cc&sq=),
|
|
and works as follows: we create a unique
|
|
[ProgID](https://docs.microsoft.com/en-us/windows/win32/com/-progid--key)
|
|
for the PWA installation with the following format:
|
|
`<BaseAppId>.<hash(Profile + AppID)>`
|
|
We use the hash due to 32-character limit for ProgID's. The registry work is
|
|
done in
|
|
[ShellUtil::AddFileAssociations](https://source.chromium.org/chromium/chromium/src/+/master:chrome/installer/util/shell_util.cc?q=%20ShellUtil::AddFileAssociations):
|
|
|
|
* Register the ProgID by adding `key HKCU\Software\Classes\<progID>` to the registry.
|
|
* Set the application name and icon for the PWA with these two keys:
|
|
* `HKCU\Software\Classes\<progID>\Application::ApplicationIcon = <path to icon in PWA install dir>,0`
|
|
* `HKCU\Software\Classes\<progID>\Application::ApplicationName = <PWA name>`
|
|
* Hook up the command to launch the launcher app
|
|
* `HKCU\Software\Classes\<progID>\shell\open\command = <launcher_app_path_in_profile> --app-id=<app_id> --profile-directory=<profile_dir>`
|
|
* Add a key to keep track of the file extensions registered for a progId,
|
|
for ease of uninstallation:
|
|
* `HKCU\Software\Classes\<progId>\File Extensions = <semicolon delimited list of extensions>`
|
|
|
|
When Chrome is launched, it writes its path into the "Last Browser" file in
|
|
the User Data dir.
|
|
When the launcher app is run, it launches Chrome using the path written into the
|
|
"Last Browser" file. Because the launcher app is in a sub-directory of the profile
|
|
directory, the "Last Browser" file is in its great grandparent directory.
|
|
|
|
When a new version of Chrome is installed, we need to update the hard links
|
|
to and copies of the installed launcher apps to use the newly installed canonical
|
|
launcher app. This is done by having the launcher app pass its version to Chrome, when
|
|
launching Chrome. If the launcher app is out of date, Chrome updates all the
|
|
launcher apps in the current user data dir.
|
|
|
|
When a PWA is uninstalled, we unregister the PWA as a handler for the file
|
|
extensions it was registered for. When a PWA changes the file extensions it can
|
|
handle, we update the registry.
|
|
|
|
## Miscellaneous
|
|
* If the same PWA is registered in multiple profiles, we distinguish them by
|
|
adding the profile name in parentheses to the PWA name, e.g,
|
|
"Example PWA (profile1)". If a PWA is uninstalled from a profile, and there is
|
|
one remaining install in another profile, we remove the profile name from the
|
|
application name.
|
|
* Windows 7 does not support some of the registry entries needed to set the
|
|
name and icon for a PWA. So, the file open context menu item for a PWA on
|
|
Windows 7 gets its name from the launcher app created for the PWA, and uses a
|
|
generic PWA icon.
|
|
|