Electron打包的软件如何使用浏览器插件

学习备份(仅用于个人记录)

结论:用不了,但是可以将插件变更为自研插件系统

Electron打包的软件 ctrl+shift+I和F12调出的系统不同,从控制台打印typeof require 结果不一样

(不确定是否是偶发)

即使你没有 Electron 软件 A 的源码 (即只有打包后的 .exeapp.asar),只要满足以下任一条件,依然可以实现"自研 JS 插件系统":

  • ✅ 你能解包并重新打包该软件(例如用于内部部署或二次开发)
  • ✅ 该软件的 渲染进程启用了 nodeIntegration: true(可通过 DevTools 控制台验证)
  • ✅ 你可以注入外部脚本(如通过启动参数、环境变量、或劫持 preload)

下面我将给出 无需原始源码、仅基于已打包 Electron 应用完整插件系统实现方案,分为两种场景:


🎯 场景一:你能修改/重打包软件(推荐)

步骤 1:解包 ASAR

bash 复制代码
npx asar extract app.asar app-unpacked

步骤 2:在主进程添加插件加载逻辑

编辑 app-unpacked/main.js(或你的主入口文件):

js 复制代码
// ====== 新增:插件系统 ======
function loadExternalPlugins(win) {
  const fs = require('fs');
  const path = require('path');
  const pluginDir = path.join(app.getPath('userData'), 'plugins');
  console.log('pluginDir',pluginDir);
  if (!fs.existsSync(pluginDir)) return;

  const files = fs.readdirSync(pluginDir).filter(f => f.endsWith('.plugin.js'));
  for (const file of files) {
    try {
      // 使用 require 动态加载插件(主进程执行)
      const pluginPath = path.join(pluginDir, file);
      delete require.cache[require.resolve(pluginPath)]; // 避免缓存
      const plugin = require(pluginPath);

      if (typeof plugin.activate === 'function') {
        plugin.activate(win); // 插件可操作 BrowserWindow
        console.log(`✅ Loaded plugin: ${file}`);
      }
    } catch (err) {
      console.error(`❌ Failed to load plugin ${file}:`, err);
    }
  }
}

在创建窗口后调用:

js 复制代码
createWindow();
loadExternalPlugins(win); // ← 新增这行

步骤 3:打包回去

bash 复制代码
npx asar pack app-unpacked app.asar

步骤 4:用户如何安装插件?

让用户在 %APPDATA%/<YourApp>/plugins/(Windows)下放入 .plugin.js 文件,例如:

js 复制代码
// hello.plugin.js
module.exports = {
  activate: (win) => {
    // 向渲染进程注入代码
    win.webContents.executeJavaScript(`
      console.log('Hello from external plugin!');
      window.EXTERNAL_PLUGIN_LOADED = true;
    `);
  }
};

✅ 优点:完全可控、安全(运行在主进程)、无需网络


🎯 场景二:你不能改主进程(只能用控制台/渲染进程)

前提:渲染进程必须能访问 Node.js(即 nodeIntegration: true 或通过 preload 暴露了 require

方法:通过 DevTools Console 动态加载远程/本地插件

步骤 1:确认是否支持 Node.js

在应用的 DevTools Console 中运行:

js 复制代码
typeof require  // 如果返回 "function",说明可用
步骤 2:加载本地插件(用户放一个 JS 文件)
js 复制代码
// 在 DevTools Console 中执行(假设插件在桌面)
(async () => {
  const fs = require('fs');
  const path = require('path');
  const pluginPath = path.join(require('os').homedir(), 'Desktop', 'my-plugin.js');
  const code = fs.readFileSync(pluginPath, 'utf8');
  eval(code); // 或用 Function() 更安全
})();
步骤 3:插件内容示例(my-plugin.js
js 复制代码
// my-plugin.js
(function () {
  console.log('🚀 自研插件已注入!');

  // 修改页面行为
  document.body.style.border = '5px solid red';

  // 添加按钮
  const btn = document.createElement('button');
  btn.innerText = 'Plugin Action';
  btn.onclick = () => alert('Hello from plugin!');
  document.body.appendChild(btn);

  // 暴露全局标志
  window.MY_PLUGIN_ACTIVE = true;
})();

⚠️ 注意:这种方式每次重启都会失效,适合临时调试。


🛡 安全建议(如果你分发插件)

  • 不要直接 eval() 用户代码 → 改用 vm 模块沙箱(主进程)
  • 校验插件签名或哈希
  • 限制插件权限(如禁止 require('child_process')

🔧 高级:自动加载插件(无需手动执行 Console)

如果软件启动时会加载某个本地 HTML/JS(比如 index.html),你可以:

  1. 解包 ASAR

  2. 修改 index.html,在 <head> 中加入:

    html 复制代码
    <script src="../plugins/loader.js"></script>
  3. 创建 resources/plugins/loader.js

    js 复制代码
    // 自动加载 plugins 目录下的所有 .js
    const fs = require('fs');
    const path = require('path');
    const pluginDir = path.join(require('electron').remote.app.getPath('userData'), 'plugins');
    if (fs.existsSync(pluginDir)) {
      fs.readdirSync(pluginDir)
        .filter(f => f.endsWith('.js'))
        .forEach(f => {
          const code = fs.readFileSync(path.join(pluginDir, f), 'utf8');
          new Function(code)(); // 沙箱执行
        });
    }

✅ 这样用户只需把 .js 放入 plugins 文件夹,启动即生效!


✅ 总结:无源码也能加插件的方案

条件 方案 持久性 安全性
能重打包 ASAR 主进程动态 require 插件 ✅ 永久 ✅ 高(可控)
不能改主进程,但 nodeIntegration=true DevTools 手动 eval 插件 ❌ 临时 ⚠️ 低
能改 ASAR 中的 HTML 注入 loader.js 自动加载 ✅ 永久 ✅ 中(可用 Function 沙箱)

💡 最终建议

即使没有源码,解包 → 修改主进程/HTML → 重打包 是最稳定、最接近"原生插件系统"的方式。

Electron 应用天生就是"可破解可扩展"的,这是它的特性,不是漏洞。

如果你需要,我可以提供:

  • 一键解包/打包脚本
  • 插件加载器模板
  • 沙箱执行示例

只需告诉我你的操作系统和软件是否允许重打包 😊

相关推荐
search75 小时前
前端设计:CRG 3--CDC error
前端
治金的blog5 小时前
vben-admin和vite,ant-design-vue的结合的联系
前端·vscode
利刃大大6 小时前
【Vue】Vue2 和 Vue3 的区别
前端·javascript·vue.js
Lhuu(重开版7 小时前
JS:正则表达式和作用域
开发语言·javascript·正则表达式
荔枝一杯酸牛奶8 小时前
HTML 表单与表格布局实战:两个经典作业案例详解
前端·html
Charlie_lll8 小时前
学习Three.js–纹理贴图(Texture)
前端·three.js
yuguo.im8 小时前
我开源了一个 GrapesJS 插件
前端·javascript·开源·grapesjs
安且惜8 小时前
带弹窗的页面--以表格形式展示
前端·javascript·vue.js
摘星编程9 小时前
用React Native开发OpenHarmony应用:NFC读取标签数据
javascript·react native·react.js
GISer_Jing9 小时前
AI驱动营销:业务技术栈实战(From AIGC,待总结)
前端·人工智能·aigc·reactjs