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:
HKCU\Software\Classes\<progID>
to the registry.HKCU\Software\Classes\<progID>\Application::ApplicationIcon = <path to icon in PWA install dir>,0
HKCU\Software\Classes\<progID>\Application::ApplicationName = <PWA name>
HKCU\Software\Classes\<progID>\shell\open\command = <launcher_app_path_in_profile> --app-id=<app_id> --profile-directory=<profile_dir>
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.