You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用pkg打包Node.js应用调用外部可执行文件时出现ENOENT错误

问题:pkg打包后execFile调用exe出现ENOENT错误(本地运行正常)

本地环境中使用child_process.execFile调用可执行文件一切正常,但通过pkg工具打包成exe后运行,出现ENOENT错误。已通过fs.existsSync()确认文件路径返回true,但仍无法执行。

相关信息

业务代码(index.js)

const { execFile } = require("child_process");
const fs = require("fs");
const execDirectory = path.join(__dirname, "./executables");
const determineActiveWindows = async (appDataDirectory) => {
  const command = `${execDirectory}\\determineActiveWindows.exe`;
  console.log("file exists", fs.existsSync(command));
  console.log("command", command);
  execFile(
    command,
    ["--appDataDirectory", appDataDirectory],
    (err, stdout, sterr) => {
      if (err) console.error(err);
      if (stdout) console.log(stdout);
      if (sterr) console.error(sterr);
    }
  );
};

错误日志

file exists true
command C:\snapshot\MinimizeWindows\build\app\executables\determineActiveWindows.exe
Error: spawn C:\snapshot\MinimizeWindows\build\app\executables\determineActiveWindows.exe ENOENT
    at Process.ChildProcess._handle.onexit (node:internal/child_process:283:19)
    at onErrorNT (node:internal/child_process:478:16)
    at processTicksAndRejections (node:internal/process/task_queues:83:21)
    at process.runNextTicks [as _tickCallback] (node:internal/process/task_queues:65:3)
    at Function.runMain (pkg/prelude/bootstrap.js:1984:13)
    at node:internal/main/run_main_module:17:47 {
  errno: -4058,
  code: 'ENOENT',
  syscall: 'spawn C:\\snapshot\\MinimizeWindows\\build\\app\\executables\\determineActiveWindows.exe',
  path: 'C:\\snapshot\\MinimizeWindows\\build\\app\\executables\\determineActiveWindows.exe',
  spawnargs: [
    '--appDataDirectory',
    'appName'
  ],
  cmd: 'C:\\snapshot\\MinimizeWindows\\build\\app\\executables\\determineActiveWindows.exe --appDataDirectory appName'
}

项目目录结构

-build
---app
------executables
---------determineActiveWindows.exe
------index.js

pkg打包命令

pkg -c package.json build/app/index.js 

package.json中的pkg配置

"pkg": {
    "targets": ["node16-win-x64"],
    "scripts": "build/**/*.js",
    "assets": "build/**/*",
    "outputPath": "dist"
  }

解决方法

1. 修正exe路径获取逻辑(核心修复)

pkg的快照目录是虚拟的,__dirname指向的是打包时的快照路径,并非运行时实际文件所在路径。需要通过process.execPath获取打包后主exe的实际目录,再拼接目标exe路径:

修改后的代码:

const { execFile } = require("child_process");
const fs = require("fs");
const path = require("path"); // 补上缺失的path模块引入

// 获取打包后主exe所在的实际目录
const appExecDir = path.dirname(process.execPath);
// 拼接目标exe的实际路径
const command = path.join(appExecDir, "executables", "determineActiveWindows.exe");

const determineActiveWindows = async (appDataDirectory) => {
  console.log("file exists", fs.existsSync(command));
  console.log("command", command);
  execFile(
    command,
    ["--appDataDirectory", appDataDirectory],
    (err, stdout, sterr) => {
      if (err) console.error(err);
      if (stdout) console.log(stdout);
      if (sterr) console.error(sterr);
    }
  );
};

2. 优化pkg的assets配置

当前assets配置范围过广,可能导致资源识别异常,改为仅打包需要的exe文件:

"pkg": {
  "targets": ["node16-win-x64"],
  "scripts": "build/**/*.js",
  "assets": "build/app/executables/**/*.exe", // 精确匹配需要的exe
  "outputPath": "dist"
}

3. 应急变通:使用exec替代execFile

若上述方法仍未解决,可尝试通过系统shell执行命令(exec会调用shell处理路径):

const { exec } = require("child_process");
// ... 其他路径逻辑不变
exec(`${command} --appDataDirectory ${appDataDirectory}`, (err, stdout, sterr) => {
  if (err) console.error(err);
  if (stdout) console.log(stdout);
  if (sterr) console.error(sterr);
});

4. 手动验证资源打包情况

打包完成后,检查dist目录下是否存在executables文件夹及对应exe文件。若缺失,手动复制build/app/executables到dist目录后再测试。

内容的提问来源于stack exchange,提问作者Arky Asmal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 14:50:32