使用 Electron 打包可执行文件和资源:完整实战教程

一.项目结构

项目结构建议如下:

my-electron-app/

├── example.exe ← 需打包的外部程序

├── config.json ← 配置文件

├── native-lib/ ← 自定义库或 DLL

│ └── yourlib.dll

├── main.js ← Electron 主进程入口

├── index.html ← 简单渲染页面

├── package.json ← 应用与打包配置

二、安装依赖

首先初始化项目,并安装 Electron和 electron-builder:

npm init -y

npm install --save-dev electron electron-builder

三、编写主进程代码(main.js)

javascript 复制代码
const { app, BrowserWindow } = require('electron');
const path = require('path');
const fs = require('fs');
const { spawn } = require('child_process');

function createWindow() {
  const win = new BrowserWindow({
    width: 800,
    height: 600
  });

  win.loadFile('index.html');

  // 读取 JSON 配置
  const configPath = app.isPackaged
    ? path.join(process.resourcesPath, 'config.json')
    : path.join(__dirname, 'config.json');

  const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
  console.log('Loaded Config:', config);

  // 启动 example.exe
  const exePath = app.isPackaged
    ? path.join(process.resourcesPath, 'example.exe')
    : path.join(__dirname, 'example.exe');

  spawn(exePath, [], {
    cwd: app.isPackaged ? process.resourcesPath : __dirname,
    detached: true,
    stdio: 'ignore'
  });
}

app.whenReady().then(createWindow);

四、HTML 页面(index.html)

html 复制代码
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Electron Resource Demo</title>
</head>
<body>
  <h1>Hello from Electron!</h1>
  <p>example.exe 已在后台执行。</p>
</body>
</html>

五、配置 package.json

关键配置在于 build 部分,确保你指定了所有需要打包的资源文件。

javascript 复制代码
{
  "name": "example-electron",
  "version": "1.0.0",
  "main": "main.js",
  "scripts": {
    "start": "electron .",
    "dist": "electron-builder"
  },
  "build": {
    "appId": "com.skydimo.exampleapp",
    "productName": "Electron Resource Example",
    "files": [
      "**/*"
    ],
    "extraResources": [
      {
        "from": "example.exe",
        "to": "resources/example.exe"
      },
      {
        "from": "config.json",
        "to": "config.json"
      },
      {
        "from": "native-lib/",
        "to": "native-lib"
      }
    ],
    "win": {
      "target": "nsis",
      "icon": "icon.ico"
    },
    "nsis": {
      "oneClick": false,
      "allowToChangeInstallationDirectory": true
    }
  },
  "devDependencies": {
    "electron": "^28.0.0",
    "electron-builder": "^24.0.0"
  }
}

说明:

  • extraResources: 是关键,它将你自定义的 .exe.json、DLL 文件一并打包到最终的 resources 文件夹中;

  • process.resourcesPath: Electron 打包后会将所有 extraResources 放到这里;

  • app.isPackaged: 判断是否是打包后的运行环境。

六、运行 & 打包

启动开发环境:

npm start

打包生成 .exe

npm run dist

输出目录默认在 dist/,你会看到:

dist/

├── win-unpacked/

├── Electron Resource Example Setup 1.0.0.exe ← 安装包

七、测试打包后行为

打包后双击运行 .exe 安装程序后,你的应用应该能:

  • 正常打开窗口;

  • 正确读取配置文件;

  • 成功启动 example.exe

  • 正常加载 DLL 等附加库文件(如你使用的是本地模块)。

小贴士

场景 处理方式
配置文件读取 fs.readFileSync(path) 搭配 process.resourcesPath
加载本地库 放在 native-lib/ 目录下,打包配置中加上路径
执行外部程序 使用 spawn(),避免阻塞主线程
调试路径问题 console.log(process.resourcesPath) 看清真实路径

总结

通过 electron-builderextraResources 配置,我们可以轻松地将自定义的 .exe 程序、.json 配置文件、本地库一并打包,并通过 Node.js 的路径处理函数在运行时加载它们。这不仅能保持项目结构清晰,也让部署和运行更简单稳定。

注意事项:运行时错误与调试建议

即使按照博客教程一步步来,也有可能在打包后遇到一些运行时错误。下面是一些 常见错误场景 和对应的 解决建议 ,帮助你根据实际情况灵活调整 main.jspackage.json

1. 找不到资源文件 / 配置文件

错误现象:

ENOENT: no such file or directory, open '.../config.json'

解决方法:
  • 问题来源 :开发环境用的是 __dirname,但打包后要用 process.resourcesPath

  • 解决方案:统一路径判断:

const configPath = app.isPackaged

? path.join(process.resourcesPath, 'config.json')

: path.join(__dirname, 'config.json');

2. example.exe 无法启动或崩溃

错误现象:
  • Electron 报错 spawn ENOENT

  • example.exe 启动了但马上退出;

  • 没有任何反馈。

解决方法:
  • 确认文件是否被打包 :打包后去 dist/win-unpacked/resources/ 看是否有 example.exe

  • 调整启动方式

spawn(exePath, [], {

cwd: path.dirname(exePath),

detached: true,

stdio: 'ignore'

});

  • example.exe 有依赖项(如 DLL) :确保这些 DLL 也通过 extraResources 被打包进来。

3. DLL/动态库加载失败

解决方法:
  • .dll 文件和 .exe 放在同一目录,或在 native-lib/ 中统一管理;

  • 添加:

"extraResources": [

{

"from": "native-lib/",

"to": "native-lib"

}

]

  • 程序中使用完整路径引入 DLL:

const libPath = app.isPackaged

? path.join(process.resourcesPath, 'native-lib', 'yourlib.dll')

: path.join(__dirname, 'native-lib', 'yourlib.dll');

4. 图标不生效 / 打包失败

可能原因:
  • 图标不是 .ico 格式;

  • 图标路径不正确。

解决方法:
  • icon.ico 放在项目根目录;

  • 配置:

"win": {

"icon": "icon.ico"

}

终极调试技巧

console.log('App Path:', app.getAppPath());

console.log('Resources Path:', process.resourcesPath);

console.log('Is Packaged:', app.isPackaged);

这些日志可以让你在运行时清楚知道资源到底应该在哪、程序是打包状态还是开发状态。

建议:打包前 checklist

检查项 是否确认 ✅
所有资源是否加进 extraResources
所有路径是否做了 isPackaged 判断
example.exe 是否独立可运行
所有 DLL 是否与 EXE 同目录
控制台是否打印真实路径调试信息

要是打包之后运行遇到问题,咱们可以一起交流看看,你也可以把 main.jspackage.json 发过来,我这边也帮着看一眼,或许能一起摸索出个思路来,把 .exe 和资源搞定

相关推荐
counterxing21 小时前
我把 Codex 里的 Skills 做成了一个 MCP,还支持分享
前端·agent·ai编程
wangqiaowq21 小时前
windows下nginx的安装
linux·服务器·前端
之歆21 小时前
DAY_12JavaScript DOM 完全指南(二):实战与性能篇
开发语言·前端·javascript·ecmascript
发现一只大呆瓜21 小时前
Vite凭什么这么快?3分钟带你彻底搞懂 Vite 热更新的幕后黑手
前端·面试·vite
Maimai1080821 小时前
React如何用 @microsoft/fetch-event-source 落地 SSE:比原生 EventSource 更灵活的实时推送方案
前端·javascript·react.js·microsoft·前端框架·reactjs·webassembly
candyTong1 天前
Claude Code 的 Edit 工具是怎么工作的
javascript·后端·架构
kyriewen1 天前
产品经理把PRD写成“天书”,我用AI半小时重写了一遍,他当场愣住
前端·ai编程·cursor
humcomm1 天前
元框架的工作原理详解
前端·前端框架
canonical_entropy1 天前
Attractor Before Harness: AI 大规模开发的方法论
前端·aigc·ai编程
zhangxingchao1 天前
多 Agent 架构到底怎么选?从 Claude Agent Teams、Cognition/Devin 到工程落地原则
前端·人工智能·后端