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

游戏启动器打包便携版后,fs.createWriteStream下载路径异常问题

解决Electron便携版打包后文件保存路径错误问题

问题原因

用npm start运行时,Node.js当前工作目录是项目根目录,相对路径会指向正确的当前目录;但Electron打包为便携版后,程序默认的当前工作目录会被设置为系统临时目录(%appdata%/local/temp),直接使用相对路径会导致文件被写入临时目录,而非可执行文件所在的目录。

解决方案

核心是获取Electron便携版可执行文件的实际所在目录,以此为基准拼接文件保存路径,而非依赖默认的当前工作目录。

主进程中直接处理

如果代码运行在Electron主进程,可直接通过app模块获取可执行文件路径:

const { app } = require('electron');
const path = require('path');
const fs = require('fs');
const needle = require('needle');

// 获取便携版EXE所在的目录
const appRootDir = path.dirname(app.getPath('exe'));

// 处理清单文件中的路径
let getDirectory = path.dirname(data);
let getFileName = path.basename(data);
// 当目录为当前目录时,清空避免多余路径拼接
if (getDirectory === '.' || getDirectory === undefined) {
    getDirectory = '';
}

// 拼接最终保存路径(自动适配跨平台路径分隔符)
const savePath = path.join(appRootDir, getDirectory, getFileName);

// 确保目标目录存在(递归创建多级目录)
fs.mkdirSync(path.dirname(savePath), { recursive: true });

// 发起下载请求并写入文件
const request = needle.get(
    `${__PATCH_URL}${getDirectory ? `/${getDirectory}` : ''}/${getFileName}`,
    { compressed: true }
);
const stream = fs.createWriteStream(savePath);
request.pipe(stream);

渲染进程中通过IPC处理

如果代码运行在渲染进程,需通过IPC通信从主进程获取应用根目录:

主进程代码

const { app, ipcMain } = require('electron');
const path = require('path');

// 注册IPC handler,返回应用根目录
ipcMain.handle('get-app-root-dir', () => {
    return path.dirname(app.getPath('exe'));
});

渲染进程代码

const { ipcRenderer } = require('electron');
const path = require('path');
const fs = require('fs');
const needle = require('needle');

// 异步获取应用根目录
const appRootDir = await ipcRenderer.invoke('get-app-root-dir');

// 后续路径处理与主进程逻辑一致
let getDirectory = path.dirname(data);
let getFileName = path.basename(data);
if (getDirectory === '.' || getDirectory === undefined) {
    getDirectory = '';
}

const savePath = path.join(appRootDir, getDirectory, getFileName);
fs.mkdirSync(path.dirname(savePath), { recursive: true });

const request = needle.get(
    `${__PATCH_URL}${getDirectory ? `/${getDirectory}` : ''}/${getFileName}`,
    { compressed: true }
);
const stream = fs.createWriteStream(savePath);
request.pipe(stream);

关键注意点

  • 使用path.join拼接路径,避免手动拼接字符串导致的跨平台路径分隔符问题。
  • 调用fs.mkdirSync并设置recursive: true,确保下载文件的目标目录存在,防止写入失败。
  • 处理getDirectory为.的情况,避免拼接出多余的./路径片段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 02:44:53