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.
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
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,
and works as follows: we create a unique
ProgID
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:
- 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.
- 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.