游戏启动器打包便携版后,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
相关产品推荐
相关产品推荐

