Electron Extensions API 详解:加载、管理与监听 Chrome 扩展的完整指南
Electron Extensions API 详解加载、管理与监听 Chrome 扩展的完整指南【免费下载链接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS项目地址: https://gitcode.com/GitHub_Trending/el/electron本文围绕 Electron 的Extensions类展开介绍如何通过session.extensions在 Electron 应用中加载未打包unpacked的 Chrome 扩展管理其生命周期并监听extension-loaded、extension-ready、extension-unloaded等实例事件同时结合 Electron 源码中electron_api_extensions.cc与electron_extension_system.cc的实现剖析路径校验、临时会话限制、allowFileAccess选项和加载警告等底层机制帮助你写出可靠的扩展集成代码。获取 Extensions 实例Session的extensions属性Extensions类**不会从electron 模块直接导出**。它只能作为其他 API 方法的返回值使用具体获取方式是访问Session实例的extensions 属性const { session } require(electron) const extensions session.defaultSession.extensions该属性在 Session 文档 中声明为只读ses.extensionsReadonly每个Session对应一个独立的扩展实例。因此扩展是按 session 安装的使用session.fromPartition(persist:...)创建的持久化 session 加载的扩展只属于该 session且不同 session 之间互不可见。注意旧版 APIses.loadExtension/ses.removeExtension/ses.getExtension/ses.getAllExtensions已被标记为弃用Deprecated官方推荐使用新的ses.extensions.loadExtension等 API见 session.md。实例事件Extensions实例是一个事件发射器共提供三个实例事件。从源码 electron_api_extensions.h 可以看到C 侧的Extensions类实现了extensions::ExtensionRegistryObserver接口三个 JS 事件分别是 ChromiumExtensionRegistry观察者回调OnExtensionLoaded、OnExtensionReady、OnExtensionUnloaded的直通映射见 electron_api_extensions.ccvoid Extensions::OnExtensionLoaded(content::BrowserContext* browser_context, const extensions::Extension* extension) { Emit(extension-loaded, extension); } void Extensions::OnExtensionUnloaded(content::BrowserContext* browser_context, const extensions::Extension* extension, extensions::UnloadedExtensionReason reason) { Emit(extension-unloaded, extension); } void Extensions::OnExtensionReady(content::BrowserContext* browser_context, const extensions::Extension* extension) { Emit(extension-ready, extension); }事件extension-loaded返回值eventEventextensionExtension扩展被加载后发出。每当一个扩展被加入该 session 的“enabled”扩展集合时就会触发包括通过extensions.loadExtension加载的扩展扩展被重新加载的场景从崩溃中恢复扩展自身请求重载调用chrome.runtime.reload()。事件extension-unloaded返回值eventEventextensionExtension扩展被卸载后发出。当调用extensions.removeExtension时触发。从源码 electron_extension_system.cc 可以看到RemoveExtension底层是调用UnloadExtension(extension_id, UnloadedExtensionReason::UNINSTALL)即以“卸载”原因通知扩展系统移除该扩展进而触发OnExtensionUnloaded回调。事件extension-ready返回值eventEventextensionExtension扩展已加载、且所有必要的浏览器状态都已初始化以支持其 background page 启动后发出。也就是说extension-loaded表示扩展元数据注册完成而extension-ready表示它已可完整运行例如可以开始执行 background 逻辑。在 spec/extensions-spec.ts 的测试中可以看到典型的“加载 ready”监听写法const loadedPromise once(customSession.extensions, extension-loaded) // ... 并监听 extension-ready事件与加载 Promise 配合使用可以精确判断扩展可用的时机再执行依赖扩展的行为。实例方法Extensions实例提供四个实例方法均在 C 侧通过gin::ObjectTemplateBuilder注册见 electron_api_extensions.cc.SetMethod(loadExtension, Extensions::LoadExtension) .SetMethod(removeExtension, Extensions::RemoveExtension) .SetMethod(getExtension, Extensions::GetExtension) .SetMethod(getAllExtensions, Extensions::GetAllExtensions)extensions.loadExtension(path[, options])pathstring - 包含未打包 Chrome 扩展的目录路径optionsObject可选allowFileAccessboolean - 是否允许扩展通过file://协议读取本地文件并将 content script 注入到file://页面。例如在file://URL 上加载 DevTools 扩展时必须开启此选项。默认值为false。返回PromiseExtension- 扩展加载完成后 resolve。该方法在扩展无法加载时会抛出异常Promise reject。如果扩展安装时存在警告例如扩展请求了 Electron 不支持的某个 API警告会输出到控制台——从源码看这些警告以ExtensionLoadWarning的类别名发出electron_api_extensions.ccif (!error_msg.empty()) util::EmitWarning(promise.isolate(), error_msg, ExtensionLoadWarning); promise.Resolve(extension)这一点在测试中也有直接验证加载带有格式错误的host_permissions的扩展时扩展仍会加载成功但会收到警告见 spec/extensions-spec.tsawait expectWarningMessages( async () { const extPath path.join(fixtures, extensions, host-permissions, malformed) await customSession.extensions.loadExtension(extPath) }, { name: ExtensionLoadWarning, message: /URL pattern malformed_host is malformed/ } )Electron 不支持完整的 Chrome 扩展 API 范围仅支持一个子集主要用于 DevTools 扩展和 Chromium 内部扩展支持的 manifest 键与chrome.*API 明细见 Chrome Extension Support。另外注意一个历史行为变更在较早版本的 Electron 中加载过的扩展会在后续应用启动时自动保留现在不再如此——如果希望扩展被加载必须在应用每次启动时都调用loadExtension。典型用法加载 React DevTools 扩展const { app, session } require(electron) const path require(node:path) app.whenReady().then(async () { await session.defaultSession.extensions.loadExtension( path.join(__dirname, react-devtools), // allowFileAccess is required to load the DevTools extension on file:// URLs. { allowFileAccess: true } ) // Note that in order to use the React DevTools extension, youll need to // download and unzip a copy of the extension. })该 API不支持加载已打包.crx的扩展只能加载 unpacked 目录。约束条件与底层实现loadExtension有以下硬性约束均可在 C 实现 LoadExtension 中找到对应代码必须在app的ready事件之后调用。路径必须是绝对路径。源码中显式校验并拒绝相对路径if (!extension_path.IsAbsolute()) { promise.RejectWithErrorMessage( The path to the extension in loadExtension must be absolute); return handle; }这就是为什么示例中用path.join(__dirname, react-devtools)拼出绝对路径而不是直接传react-devtools。不能在内存非持久化session 中加载。源码检查IsOffTheRecord()拒绝时抛出Extensions cannot be loaded in a temporary sessionelectron_api_extensions.cc。测试用例 spec/extensions-spec.ts 验证了这一行为it(loading an extension in a temporary session throws an error, async () { const customSession session.fromPartition(require(uuid).v4()) await expect( customSession.extensions.loadExtension(path.join(fixtures, extensions, content-script-test)) ).to.eventually.be.rejectedWith(Extensions cannot be loaded in a temporary session) })也就是说只有defaultSession或带persist:前缀的 partition 才能加载扩展session.fromPartition(uuid)这类临时 session 会直接抛错。allowFileAccess的底层含义。源码中该选项会被映射为 Chromium 扩展加载标志electron_api_extensions.ccint load_flags extensions::Extension::FOLLOW_SYMLINKS_ANYWHERE; gin_helper::Dictionary options; if (args-GetNext(options)) { bool allowFileAccess false; options.Get(allowFileAccess, allowFileAccess); if (allowFileAccess) load_flags | extensions::Extension::ALLOW_FILE_ACCESS; }即不开启时扩展默认只能作用于http://、https://等网络协议页面file://页面无法被 content script 注入而开启ALLOW_FILE_ACCESS后扩展才被允许访问file://资源。这正是 DevTools 类扩展在本地file://页面上工作时必须传{ allowFileAccess: true }的原因。extensions.removeExtension(extensionId)extensionIdstring - 要移除的扩展 ID卸载指定扩展。该 API 同样不能在app的ready事件之前调用。在 spec/extensions-spec.ts 中可以看到测试清理时的标准用法遍历getAllExtensions()并逐一removeExtension确保测试之间互不污染afterEach(() { for (const e of session.defaultSession.extensions.getAllExtensions()) { session.defaultSession.extensions.removeExtension(e.id) } })extensions.getExtension(extensionId)extensionIdstring - 要查询的扩展 ID返回Extension | null- 给定 ID 的已加载扩展。源码实现直接查询该 browser context 的ExtensionRegistry未找到时返回nullelectron_api_extensions.cc。该 API 不能在app的ready事件之前调用。extensions.getAllExtensions()返回Extension[]- 所有已加载扩展的列表。一个值得注意的细节实现中会过滤掉 Chromium 的 component 扩展如内置的 PDF 查看器只返回由用户通过loadExtension加载的扩展electron_api_extensions.ccfor (const auto extension : extensions) { if (extension-location() ! extensions::mojom::ManifestLocation::kComponent) extensions_vector.emplace_back(extension.get()); }该 API 也不能在app的ready事件之前调用。返回的 Extension 对象结构loadExtensionresolve 以及各事件回传的都是 Extension 对象包含字段idstring - 扩展 IDchrome.runtime.id对应的值可用于后续removeExtension/getExtensionmanifestany - 扩展 manifest 数据的一份拷贝namestringpathstring - 扩展的文件路径versionstringurlstring - 扩展的chrome-extension://URL拿到id后即可与getExtension/removeExtension配合做完整的加载—查询—卸载生命周期管理。支持的扩展 API 范围速览由于loadExtension文档明确指向了支持范围说明这里给出要点完整清单见 docs/api/extensions.md完整支持chrome.devtools.inspectedWindow、chrome.devtools.network、chrome.devtools.panels、chrome.scripting、chrome.webRequest注意 Electron 自身的webRequest模块在冲突时优先于chrome.webRequest。部分支持chrome.runtime支持lastError、id属性及getBackgroundPage、getManifest、getPlatformInfo、getURL、connect、sendMessage、reload方法与onStartup、onInstalled、onSuspend、onSuspendCanceled、onConnect、onMessage事件chrome.tabs支持sendMessage、reload、executeScriptquery与update为部分支持且-1不代表“当前活动标签”chrome.storage仅local不支持sync/managedchrome.managementgetAll、get、getSelf、getPermissionWarningsById、getPermissionWarningsByManifest与onEnabled/onDisabledchrome.extension仅lastError、getURL、getBackgroundPage。支持的 manifest 键name、version、author、permissions、content_scripts、default_locale、devtools_page、short_name、host_permissionsManifest V3、manifest_version、backgroundManifest V2、minimum_chrome_version。列表之外的 API 即使当前碰巧可用其支持也是临时的随时可能移除。小结Extensions实例只能通过session.extensions获取扩展按 session 隔离且每次应用启动都必须重新loadExtension。loadExtension要求绝对路径、仅支持 unpacked 扩展、仅限持久化 sessionallowFileAccess: true是扩展作用于file://页面如 DevTools 扩展的必要开关。加载失败 reject、加载警告走ExtensionLoadWarning、临时会话抛Extensions cannot be loaded in a temporary session——这些行为均有 spec/extensions-spec.ts 中的测试用例佐证可用于回归验证。通过extension-loaded/extension-ready/extension-unloaded三个事件可以精确掌握扩展从注册、就绪到卸载的完整生命周期。【免费下载链接】electron:electron: Build cross-platform desktop apps with JavaScript, HTML, and CSS项目地址: https://gitcode.com/GitHub_Trending/el/electron创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

ripgrep(rg)深度解析:高速递归正则搜索工具的原理、基准数据与实战指南

ripgrep(rg)深度解析:高速递归正则搜索工具的原理、基准数据与实战指南

ripgrep(rg)深度解析:高速递归正则搜索工具的原理、基准数据与实战指南 【免费下载链接】ripgrep ripgrep recursively searches directories for a regex pattern while respecting your gitignore 项目地址: https://gitcode.com/GitHub_…

2026/10/25 19:28:44 阅读更多 →
SpotDL 新手完整指南:5 分钟跑通 Spotify 歌单下载

SpotDL 新手完整指南:5 分钟跑通 Spotify 歌单下载

SpotDL 新手完整指南:5 分钟跑通 Spotify 歌单下载 【免费下载链接】spotify-downloader Download your Spotify playlists and songs along with album art and metadata (from YouTube if a match is found). 项目地址: https://gitcode.com/GitHub_Trending/sp…

2026/11/10 21:02:20 阅读更多 →
openpilot Joystick 调试工具详解:用 testJoystick 消息链路实时调试横纵向控制

openpilot Joystick 调试工具详解:用 testJoystick 消息链路实时调试横纵向控制

openpilot Joystick 调试工具详解:用 testJoystick 消息链路实时调试横纵向控制 【免费下载链接】openpilot openpilot is an operating system for robotics. Currently, it upgrades the driver assistance system on 300 supported cars. 项目地址: https://gi…

2026/10/24 10:49:26 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/9 14:01:10 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/9 14:56:39 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/10 2:03:25 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/10 16:14:15 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/10 12:51:50 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/9 14:01:11 阅读更多 →

日新闻

周新闻

月新闻