Electron 项目实现下载文件监听

Electron 项目实现下载文件监听

随着现代应用程序功能的不断扩展,用户对下载文件的需求也越来越高。特别是在 Electron 应用程序中,提供一个高效、可靠的下载管理功能是提升用户体验的

关键之一。本文将详细介绍如何在 Electron 项目中实现下载文件的监控,包括进度信息的实时更新,并将这些信息返回给前端。同时,还会讲解如何避免用户点击下载按钮时弹出下载对话框,

直接下载到设置的默认路径。本文将为你提供详细的步骤和代码示例,帮助你快速实现这一功能。

目标
  1. 实现下载文件的监听,包括下载进度和最终状态。
  2. 将下载详细信息发送到前端并实时显示。
  3. 避免用户点击下载按钮时弹出下载对话框,直接下载到设置的默认路径。
步骤
  1. 设置项目环境
  2. 创建主窗口
  3. 监听下载事件
  4. 发送下载状态到前端
  5. 前端接收并显示下载状态
  6. 避免弹出下载对话框

1. 设置项目环境

首先,确保你已经安装了 Electron。如果还没有安装,可以使用以下命令进行安装:

bash 复制代码
npm install electron --save-dev

2. 创建主窗口

在项目的主文件(通常是 main.js)中,创建主窗口并加载前端页面。

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

let mainWindow;

function createWindow() {
    mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            nodeIntegration: true,
            contextIsolation: false,
            preload: path.join(__dirname, 'preload.js')
        }
    });

    mainWindow.loadFile('index.html');
}

app.on('ready', async () => {
    await createWindow();
});

3. 监听下载事件

main.js 中,监听 will-download 事件,设置默认下载路径,并监控下载状态。

javascript 复制代码
const { app, BrowserWindow, session, ipcMain } = require('electron');
const path = require('path');

let mainWindow;

function createWindow() {
    mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            nodeIntegration: true,
            contextIsolation: false,
            preload: path.join(__dirname, 'preload.js')
        }
    });

    mainWindow.loadFile('index.html');
}

app.on('ready', async () => {
    await createWindow();

    let session = mainWindow.webContents.session;

    session.on('will-download', (event, item, webContents) => {
        // 获取当前用户的下载文件夹路径
        const defaultDownloadPath = app.getPath('downloads');
        const suggestedFileName = item.getFilename();
        const savePath = path.join(defaultDownloadPath, suggestedFileName);

        // 设置下载项的保存路径
        item.setSavePath(savePath);

        // 发送下载开始信息到前端
        mainWindow.webContents.send('download-started', { filename: suggestedFileName, savePath });

        // 初始化已接收字节数
        let receivedBytes = 0;

        // 监听下载进度
        item.on('updated', (event, state) => {
            if (state === 'interrupted') {
                mainWindow.webContents.send('download-interrupted', { filename: suggestedFileName });
            } else if (state === 'progressing') {
                if (item.isPaused()) {
                    mainWindow.webContents.send('download-paused', { filename: suggestedFileName });
                } else {
                    receivedBytes = item.getReceivedBytes();
                    let progress = Math.round((receivedBytes / item.getTotalBytes()) * 100);
                    mainWindow.webContents.send('download-progress', { filename: suggestedFileName, progress });
                }
            }
        });

        // 监听下载完成
        item.once('done', (event, state) => {
            if (state === 'completed') {
                mainWindow.webContents.send('download-completed', { filename: suggestedFileName, savePath });
            } else {
                mainWindow.webContents.send('download-failed', { filename: suggestedFileName, error: state });
            }
        });
    });
});

4. 发送下载状态到前端

在上面的代码中,我们使用 mainWindow.webContents.send 方法将下载状态发送到前端。这些状态包括下载开始、下载进度、下载中断、下载暂停和下载完成。

5. 前端接收并显示下载状态

在前端页面(通常是 index.html)中,使用 Electron 的 ipcRenderer 模块接收这些状态并显示。

index.html
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Electron Download Monitor</title>
    <style>
        body {
            font-family: Arial, sans-serif;
        }
        .download-status {
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <h1>Electron Download Monitor</h1>
    <button id="download-button">开始下载</button>
    <div id="download-status" class="download-status"></div>

    <script src="renderer.js"></script>
</body>
</html>
renderer.js
javascript 复制代码
const { ipcRenderer } = require('electron');

document.getElementById('download-button').addEventListener('click', () => {
    // 触发下载操作
    ipcRenderer.send('start-download');
});

// 监听下载开始事件
ipcRenderer.on('download-started', (event, data) => {
    const statusDiv = document.getElementById('download-status');
    statusDiv.innerHTML += `<p>下载开始: ${data.filename} 到 ${data.savePath}</p>`;
});

// 监听下载进度事件
ipcRenderer.on('download-progress', (event, data) => {
    const statusDiv = document.getElementById('download-status');
    statusDiv.innerHTML += `<p>下载进度: ${data.filename} - ${data.progress}%</p>`;
});

// 监听下载中断事件
ipcRenderer.on('download-interrupted', (event, data) => {
    const statusDiv = document.getElementById('download-status');
    statusDiv.innerHTML += `<p>下载中断: ${data.filename}</p>`;
});

// 监听下载暂停事件
ipcRenderer.on('download-paused', (event, data) => {
    const statusDiv = document.getElementById('download-status');
    statusDiv.innerHTML += `<p>下载暂停: ${data.filename}</p>`;
});

// 监听下载完成事件
ipcRenderer.on('download-completed', (event, data) => {
    const statusDiv = document.getElementById('download-status');
    statusDiv.innerHTML += `<p>下载完成: ${data.filename} 保存到 ${data.savePath}</p>`;
});

// 监听下载失败事件
ipcRenderer.on('download-failed', (event, data) => {
    const statusDiv = document.getElementById('download-status');
    statusDiv.innerHTML += `<p>下载失败: ${data.filename} - 错误: ${data.error}</p>`;
});

6. 避免弹出下载对话框

在上面的代码中,我们已经在 will-download 事件的回调函数中设置了默认下载路径,从而避免弹出下载对话框。具体代码如下:

javascript 复制代码
session.on('will-download', (event, item, webContents) => {
    // 获取当前用户的下载文件夹路径
    const defaultDownloadPath = app.getPath('downloads');
    const suggestedFileName = item.getFilename();
    const savePath = path.join(defaultDownloadPath, suggestedFileName);

    // 设置下载项的保存路径
    item.setSavePath(savePath);

    // 发送下载开始信息到前端
    mainWindow.webContents.send('download-started', { filename: suggestedFileName, savePath });

    // 初始化已接收字节数
    let receivedBytes = 0;

    // 监听下载进度
    item.on('updated', (event, state) => {
        if (state === 'interrupted') {
            mainWindow.webContents.send('download-interrupted', { filename: suggestedFileName });
        } else if (state === 'progressing') {
            if (item.isPaused()) {
                mainWindow.webContents.send('download-paused', { filename: suggestedFileName });
            } else {
                receivedBytes = item.getReceivedBytes();
                let progress = Math.round((receivedBytes / item.getTotalBytes()) * 100);
                mainWindow.webContents.send('download-progress', { filename: suggestedFileName, progress });
            }
        }
    });

    // 监听下载完成
    item.once('done', (event, state) => {
        if (state === 'completed') {
            mainWindow.webContents.send('download-completed', { filename: suggestedFileName, savePath });
        } else {
            mainWindow.webContents.send('download-failed', { filename: suggestedFileName, error: state });
        }
    });
});

总结

通过以上步骤,你可以在 Electron 项目中实现下载文件的监控,并将下载状态(包括进度信息)返回给前端。这样,用户可以实时看到下载的进度和结果。从设置项目环境到监听下载事件,再到将下载状态发送到前端并实时显示,每一步都经过详细讲解和代码示例展示。此外,还讲解了如何避免用户点击下载按钮时弹出下载对话框,直接下载到设置的默认路径。

相关推荐
quitv17 分钟前
react脚手架配置别名
前端·javascript·react.js
Gazer_S2 小时前
【现代前端框架中本地图片资源的处理方案】
前端·javascript·chrome·缓存·前端框架
贺今宵4 小时前
通过$attrs传递的未指定名称的modelValue值在子组件中修改
前端·javascript
lifire_H8 小时前
Canvas在视频应用中的技术解析
前端·javascript·音视频
十八朵郁金香10 小时前
深入理解 JavaScript 中的 this 指向
开发语言·前端·javascript
贵州晓智信息科技10 小时前
使用 Three.js 转换 GLSL 粒子效果着色器
开发语言·javascript·着色器
linkcoco11 小时前
记录h5使用navigator.mediaDevices.getUserMedia录制音视频
前端·javascript·vue·音视频·js
Mh11 小时前
代码提交校验及提交规范的实践方案
前端·javascript·架构
昨日余光11 小时前
仅需三分钟,使用Vue3.x版本组件式风格实现一个消息提示组件!
前端·javascript·css·vue.js·typescript·html
软件开发技术深度爱好者11 小时前
验证码介绍及生成与验证(HTML + JavaScript实现)
javascript