# 桌面端安装

> Chrome、Edge、Safari 与 Firefox 如何在 Windows、macOS、Linux 与 ChromeOS 上安装 web 应用，应用装在各系统的哪里，页面又如何检测安装态。

桌面端安装把一个站点变成系统级应用：拥有自己的窗口、启动器条目，以及任务栏或 Dock 上的位置。Chrome 73 与 Edge 79 在 Windows、macOS、Linux 与 ChromeOS 上通过地址栏、浏览器菜单或 `beforeinstallprompt` 安装；macOS 14 上的 Safari 17 通过 File › "Add to Dock" 安装；Windows 上的 Firefox 143 可以把站点固定为任务栏 web 应用（Firefox 143 发行说明）；更早的桌面版 Firefox 与 Safari 没有任何安装路径，而 Chromium 之外没有浏览器会触发 `beforeinstallprompt`（BCD `api.BeforeInstallPromptEvent`）。

## 工作原理

一次桌面安装由三部分组成：触发、系统注册、窗口模式。触发要么来自浏览器自己的入口（Chrome 与 Edge 在满足可安装性条件后在地址栏右端显示安装图标，三点菜单中也有安装项；Safari 用 File › "Add to Dock"；Firefox 143 用地址栏图标），要么（仅 Chromium）来自页面自己的按钮，背后是保存下来的 `BeforeInstallPromptEvent`。桌面端没有 mini-infobar；没有事件时，页面也没有可以压制的横幅。

用户接受后，浏览器写入一个系统启动器条目，应用无需先打开浏览器即可启动：

| 系统 | 浏览器创建什么 | 管理入口 |
|---|---|---|
| Windows（Chrome、Edge） | 开始菜单快捷方式；应用出现在任务栏与 Alt+Tab 中。Edge 还会把它登记到设置 › 应用 › "已安装的应用"。 | `chrome://apps`、`edge://apps` |
| macOS（Chrome、Edge） | `~/Applications/Chrome Apps.localized/` 或 `~/Applications/Edge Apps.localized/` 中的应用包，可在 Spotlight 与 Dock 中看到。 | `chrome://apps`、`edge://apps` |
| macOS（Safari 17 及以后） | `~/Applications/` 中的一个应用，由没有标签页与地址栏的 Safari 窗口打开；Cookie 与存储同 Safari 分离。 | 从"应用程序"中删除 |
| Linux（Chrome、Edge） | `~/.local/share/applications/` 中的 `.desktop` 条目，GNOME 与 KDE 启动器会读取。 | `chrome://apps`、`edge://apps` |
| ChromeOS | 可固定到任务栏的启动器条目；经由 TWA 的 Play 商店上架是另一回事。 | 启动器 › 右键 › 卸载 |

窗口模式来自 manifest。`display: standalone` 得到带系统标题栏、无浏览器界面的窗口；`minimal-ui` 加回后退、前进与刷新；`display_override: ["window-controls-overlay"]` 让页面绘制到标题栏区域，系统保留关闭、最小化与最大化按钮，并通过 `env(titlebar-area-x)`、`env(titlebar-area-y)`、`env(titlebar-area-width)` 与 `env(titlebar-area-height)` 暴露剩余区域（Chrome 105、Edge 105，仅桌面端）。窗口标题与图标来自 `name` 与 `icons`；每次启动新开窗口还是聚焦已有窗口由 `launch_handler.client_mode` 决定。

相对于浏览器标签页，取舍是具体的：应用失去地址栏、标签栏与扩展（Chrome 运行已安装应用时不显示扩展工具栏），得到 Alt+Tab 或 Cmd+Tab 中独立的窗口、以应用名称与图标署名的系统通知、角标、文件与协议处理，以及从系统启动。Chrome 与 Edge 上 Cookie 与存储同安装它的浏览器配置文件共享，因此登录态会带过去；Safari 17 上则不共享，用户需要在应用内重新登录。

## 实测行为

安装产物在磁盘上可见，这是确认某个浏览器到底做了什么的最快方式。

:::observed
在 macOS 上用 Chrome（英文界面）安装一个站点后，Finder 中出现 `~/Applications/Chrome Apps.localized/<应用名>.app`，`chrome://apps` 列出该应用，其右键菜单带有 "Uninstall `<应用名>`…" 项；在 Linux 上同样的安装写入 `~/.local/share/applications/chrome-<app id>-Default.desktop`，其中 `<app id>` 是 `chrome://apps` 链接中使用的 32 个字母的标识符。启动应用后，窗口标题栏显示 manifest 的 `name` 且没有地址栏，其 DevTools 控制台中 `matchMedia('(display-mode: standalone)').matches` 的值为 `true`。
:::

页面不需要任何浏览器私有 API 就能判断自己是否以安装态运行、得到了哪种窗口模式。媒体查询报告的是浏览器实际应用的模式，当 `display_override` 列出多项时它可能与请求的不同。

```js
const mode = ['window-controls-overlay', 'standalone', 'minimal-ui', 'fullscreen']
  .find((m) => matchMedia(`(display-mode: ${m})`).matches) ?? 'browser';

if (mode !== 'browser') {
  installButton.hidden = true;              // 已安装并以应用方式启动
}
if (mode === 'window-controls-overlay') {
  document.documentElement.classList.add('wco');   // 绘制到标题栏区域
}
```

Safari 17 与 Firefox 143 的应用在这里同样报告 `standalone`，所以该检查不需要按 user agent 分支；各浏览器之间不同的只是用户如何走到这一步。

## 另请参阅

- [Installing and uninstalling web apps](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Guides/Installing)（developer.mozilla.org）
- [Progressive Web Apps on Windows: the user experience](https://learn.microsoft.com/en-us/microsoft-edge/progressive-web-apps-chromium/ux)（learn.microsoft.com）
- [Firefox 143.0 release notes](https://www.mozilla.org/en-US/firefox/143.0/releasenotes/)（mozilla.org）
- [beforeinstallprompt 事件](/zh/reference/installation/install-prompt/)
- [可安装性条件](/zh/reference/installation/installability-criteria/)
- [卸载已安装的 PWA](/zh/reference/installation/uninstall-retention/)
- [`display_override` manifest 成员](/zh/reference/manifest/display-override/)
- [macOS Safari 上的 PWA](/zh/reference/platforms/macos-safari/)