ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Electron 最近文档(Recent Documents)实战指南:接入 Windows JumpList 与 macOS Dock 菜单

Electron 最近文档(Recent Documents)实战指南:接入 Windows JumpList 与 macOS Dock 菜单 Electron 最近文档Recent Documents实战指南接入 Windows JumpList 与 macOS Dock 菜单【免费下载链接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS项目地址: https://gitcode.com/GitHub_Trending/el/electron导读Windows 与 macOS 两大桌面系统都内置了最近使用的文档能力分别表现为任务栏 JumpList 与 Dock 菜单。Electron 通过app模块提供三个原生方法让应用可以把自己的文件加入系统级最近列表、读取列表内容并在窗口关闭时清空。本文以 docs/tutorial/recent-documents.md 为主线结合 docs/fiddles/features/recent-documents 中可直接运行的最小示例与 docs/api/app.md 的 API 契约完整覆盖添加、清除、读取三个操作并深入到 shell/browser 的 C 实现解释每个方法在 macOS / Windows 下的真实系统调用帮助你把应用无缝接入操作系统的文件工作流。功能概览系统级的最近文档入口在 Electron 应用中最近文档并非由应用自己维护而是由操作系统托管的一份清单。应用只需要通过app模块把文件路径递交给系统剩下的事情如菜单展示、去重、记录打开时间都由系统完成Windows用户右键单击任务栏中的应用图标会在JumpList中看到「最近」Recent类别。macOS用户右键或长按Dock 中的应用图标会在dock 菜单中看到最近文档此外还可以把最近文档子菜单挂进应用菜单栏。Windows 端 JumpList 与 macOS 端 Dock 菜单的典型形态如下三个 API 的平台限定非常明确从接口注释即可看出它们均标注为macOS / WindowsAPI说明平台app.addRecentDocument(path)将path指向的文件加入最近文档列表macOS、Windowsapp.clearRecentDocuments()清空最近文档列表macOS、Windowsapp.getRecentDocuments()返回最近文档数组string[]macOS、WindowsLinux 注意Electron 源码在 shell/browser/browser_linux.cc 中把这三个方法实现为空操作——AddRecentDocument直接空返回、GetRecentDocuments恒返回空数组、ClearRecentDocuments不做任何事。因此本指南的全部内容仅适用于 macOS 与 Windows 平台。核心实现三个方法背后的系统级调用理解底层实现有助于判断该在哪里调用。在 shell/browser/api/electron_api_app.cc 中Electron 把Browser类的三个 C 方法通过SetMethod暴露为 JS 层的app.addRecentDocument/clearRecentDocuments/getRecentDocuments接口声明见 shell/browser/browser.h。不同平台落地为不同的系统 APImacOSshell/browser/browser_mac.mm基于NSDocumentController。添加时用noteNewRecentDocumentURL:记录一个NSURL清空用clearRecentDocuments:读取则取recentDocumentURLs数组。也就是说 macOS 端直接对接系统文档中心与应用是否有文档窗口无关。Windowsshell/browser/browser_win.cc基于 Win32 Shell 的SHAddToRecentDocs。添加时先用SHCreateItemFromParsingName把路径解析成IShellItem再以SHARD_APPIDINFO类型连同应用的 AppUserModelID 一起提交给系统清空则把同一调用传入空指针读取会从 Windows 系统的 Recent 目录中枚举出文档列表内部使用ScopedAllowBlockingForElectron允许阻塞式 IO。从这里可以看到Windows 端最近文档与应用的AppUserModelID绑定AppUserModelID 不同JumpList 相互独立。两个平台都各自维护同一份系统级列表应用的 JS 层无需缓存任何状态。最小可运行示例完整的最近文档生命周期仓库在 docs/fiddles/features/recent-documents/main.js 中给出了一个可直接运行的完整示例覆盖创建文件 → 加入最近列表 → 窗口关闭时清空的完整生命周期配套页面 docs/fiddles/features/recent-documents/index.html 会提示用户右键应用图标查看效果const { app, BrowserWindow } require(electron/main) const fs require(node:fs) const path require(node:path) function createWindow () { const win new BrowserWindow({ width: 800, height: 600 }) win.loadFile(index.html) } const fileName recently-used.md fs.writeFile(fileName, Lorem Ipsum, () { app.addRecentDocument(path.join(__dirname, fileName)) }) app.whenReady().then(createWindow) app.on(window-all-closed, () { app.clearRecentDocuments() if (process.platform ! darwin) { app.quit() } }) app.on(activate, () { if (BrowserWindow.getAllWindows().length 0) { createWindow() } })运行逻辑解读应用启动时先用 Node 的fs.writeFile在项目根目录生成一个名为recently-used.md的占位文件模拟应用真实产生/打开了一个文档在文件写入回调里调用app.addRecentDocument(path.join(__dirname, fileName))把该文件的绝对路径交给系统主窗口照常创建监听window-all-closed当所有窗口关闭时调用app.clearRecentDocuments()清空最近列表随后若不在 macOS 上process.platform ! darwin则退出进程macOS 遵循其惯例保留进程等待activate事件重新创建窗口。需要注意fs.writeFile是异步的必须把addRecentDocument放在回调里以保证文件确实落盘后再提交给系统否则可能出现文件尚不存在就被加入列表的竞态问题。添加最近文档对系统而言一个文件想出现在最近列表里只要调用一次app.addRecentDocument(path)const { app } require(electron) const path require(node:path) const file path.join(app.getPath(desktop), foo.txt) app.addRecentDocument(file)关键点path必须是文件系统可解析的绝对路径推荐用path.join拼出完整路径后传入该方法不要求文件当前处于打开状态也不要求窗口存在只要应用进程在跑即可调用重复添加同一路径通常会被系统自动去重并提到列表最前具体去重策略由系统实现决定。按示例运行后右键应用图标macOS 上为 Dock 图标即可在最近文件列表里看到recently-used.md清空最近文档列表调用无参的app.clearRecentDocuments()即可一次性清空系统维护的整个最近列表app.clearRecentDocuments()指南示例的策略是一旦所有窗口关闭就清空列表window-all-closed事件内调用。实际产品中可根据产品语义决定清空时机例如在菜单里提供清除最近文档菜单项见下文 macOS 菜单方案提供无痕模式/敏感数据保护开关在开启时主动清空应用退出前按用户偏好决定是否保留记录。读取最近文档列表使用app.getRecentDocuments()可以取回系统当前维护的最近文档绝对路径数组const { app } require(electron) const recents app.getRecentDocuments() console.log(recents) // [/path/to/desktop/foo.txt, ...]返回值是按最近优先排序的string[]。它的典型用途包括在应用内实现最近打开子菜单、在启动欢迎页展示最近项目、或在 UI 中二次加工后回写给用户。需要说明的是getRecentDocuments拿到的是当前 AppUserModelID / NSDocumentController 语境下的列表若在写入前调用得到的自然是空数组或历史残留。macOS 专属把最近文档挂进应用菜单除了 Dock 菜单macOS 应用通常还应该在菜单栏的「File文件」菜单中暴露标准的最近文档能力。Electron 菜单模板为此提供了两个内置 role{ submenu: [ { label: Open Recent, role: recentdocuments, submenu: [ { label: Clear Recent, role: clearrecentdocuments } ] } ] }其中recentdocumentsrole 会渲染出系统维护的最近文档列表子菜单clearrecentdocumentsrole 则提供一个一键清空入口。给菜单设置角色后效果如下注意上图为 Dock 菜单展示形态作为菜单样式的直观参考菜单栏中「Open Recent」的视觉呈现方式与之类似均由系统根据应用当前状态渲染。菜单必须在 ready 之后设置文档特别强调应用菜单必须在ready事件触发之后再设置否则最近文档菜单项会处于禁用状态。标准做法是把Menu.setApplicationMenu(menu)放进app.whenReady().then(...)const { app, Menu } require(electron) const template [ // Menu template here ] const menu Menu.buildFromTemplate(template) app.whenReady().then(() { Menu.setApplicationMenu(menu) })从菜单请求文件监听 open-file 事件当用户从「Open Recent」菜单或 Dock 菜单点选某个文件时应用会收到app模块的open-file事件。完整契约见 docs/api/app.md事件回调接收event与pathstring两个参数该事件通常在应用已运行、系统想复用它打开文件时发出当文件被拖到 Dock 图标上而应用尚未启动时open-file也会在启动阶段发出。此时应用可能在ready之前就收到该事件所以务必在应用启动的最早期注册监听在 ready 之前否则会丢失此次打开请求若你打算自己接管该文件例如自行打开窗口展示内容应调用event.preventDefault()阻止系统默认行为macOS 上系统对 Finder 中双击文件/通过 Dock 唤起应用自带单实例语义新打开的请求会通过该事件派发给已存在的实例参见 docs/api/app.md 中关于 macOS 单实例机制的说明。监听示例app.on(open-file, (event, path) { event.preventDefault() // 在这里用 fs/你的编辑器逻辑打开 path })Windows 专属文件类型关联是 JumpList 生效的前提在 Windows 上使用最近文档功能时有一个关键前置条件应用必须先把自己注册为该文件类型的处理程序handler否则即使调用了addRecentDocument文件也不会出现在 JumpList 里。Windows 对应用注册的完整要求可以参考系统文档中关于 Application Registration 的说明涉及HKCU\Software\Classes下的 ProgID、文件类型与应用的关联、图标与命令行的配置等。Electron 中常见的配套做法是结合 app.setAsDefaultProtocolClient 一类的系统注册 API或用安装器在安装阶段完成文件类型关联。另一个 Windows 行为差异在于打开路径当用户从 JumpList 点击某个文件时系统会启动一个全新的应用实例并把该文件路径作为命令行参数追加传入。因此 Windows 端需要在主进程入口解析命令行参数例如用process.argv来判断是否为打开文件的冷启动再决定是新建窗口展示内容还是把文件派发给既有实例。参考实现与延伸阅读文档原文docs/tutorial/recent-documents.md可运行示例docs/fiddles/features/recent-documents/main.js 与配套页面 index.htmlAPI 完整契约app.addRecentDocument / clearRecentDocuments / getRecentDocuments、open-file事件docs/api/app.md平台底层实现macOS 走NSDocumentControllershell/browser/browser_mac.mmWindows 走SHAddToRecentDocs与 AppUserModelIDshell/browser/browser_win.ccLinux 为空实现shell/browser/browser_linux.cc模块绑定见 shell/browser/api/electron_api_app.cc系统界面层面的延伸Windows 更多任务栏集成缩略图工具栏、任务栏按钮进度等参见 docs/tutorial/windows-taskbar.mdmacOS Dock 菜单更多玩法参见 docs/tutorial/macos-dock.md小结把最近文档能力接入 Electron 应用只需记住三个对称的方法addRecentDocument提交、getRecentDocuments读取、clearRecentDocuments清空。落地时注意三件事——Windows 必须先完成文件类型关联与 AppUserModelID 环境macOS 的「Open Recent」菜单必须等ready后再挂载且open-file事件要尽早监听以捕获冷启动打开请求。配合本文给出的系统级实现细节你可以让应用在 JumpList 与 Dock 中呈现出与原生软件一致的文件工作流体验。【免费下载链接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS项目地址: https://gitcode.com/GitHub_Trending/el/electron创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表