【Electron】Electron下载功能实现

时间:2022-08-15 19:23:42

项目创建,请参考:

Electron】Electron开发入门(二):创建项目Hello Word

主进程与渲染进程通信,请参考:

【Electron】main process(主进程)和web page(渲染进程) 通信

一、项目结构

【Electron】Electron下载功能实现

二、实现代码

index.html

<!doctype html>
<html>
<head>
<meta charset="utf-8" /> 
<title>测试</title>   
    <script src="index.js"></script>
</head>
<body onload="init();">
<p>Hello World</p>
    <button onclick="down();">下载</button>
</body>
</html>


index.js

const {ipcRenderer} = require('electron')

function init(){
    //监听main process里发出的message
    ipcRenderer.on('downstate', (event, arg) => {
     alert("下载状态:" + arg); 
}) 
}

/**
* 下载
*/
function down(){
  var a="f:\\1\\1.txt";//需要下载文件的路径
  var b="f:\\3\\";//下载文件存放路径
  
  //扩展,访问局域网内共享文件
  var c="file:\\xxx.xxx.x.xxx\\test\\1.txt"; 
ipcRenderer.send('download',a+"+"+b) 

}

main.js

const electron = require('electron');// 控制应用生命周期的模块
const {app} = electron;// 创建本地浏览器窗口的模块
const {BrowserWindow} = electron;

// 指向窗口对象的一个全局引用,如果没有这个引用,那么当该javascript对象被垃圾回收的// 时候该窗口将会自动关闭
let win;
function createWindow() {
// 创建一个新的浏览器窗口
win = new BrowserWindow({width: 1104, height: 620});//570+50

// 并且装载应用的index.html页面
win.loadURL(`file://${__dirname}/html/index.html`);

// 打开开发工具页面
win.webContents.openDevTools();

/*******************实现代码************************** */
win.webContents.session.on('will-download', (event, item, webContents) => {
//设置文件存放位置,如果用户没有设置保存路径,Electron将使用默认方式来确定保存路径(通常会提示保存对话框)
item.setSavePath(savepath+item.getFilename())
item.on('updated', (event, state) => {
if (state === 'interrupted') {
console.log('Download is interrupted but can be resumed')
} else if (state === 'progressing') {
if (item.isPaused()) {
console.log('Download is paused')
} else {
console.log(`Received bytes: ${item.getReceivedBytes()}`)
}
}
})
item.once('done', (event, state) => {
if (state === 'completed') {
console.log('Download successfully')
//回显 调用渲染进程方法
win.webContents.send('downstate',state)
} else {
console.log(`Download failed: ${state}`)
//回显 调用渲染进程方法
win.webContents.send('downstate',state)
}
})
})
/*******************实现代码************************** */

// 当窗口关闭时调用的方法
win.on('closed', () => {
// 解除窗口对象的引用,通常而言如果应用支持多个窗口的话,你会在一个数组里
// 存放窗口对象,在窗口关闭的时候应当删除相应的元素。
win = null;
});

}
// 当Electron完成初始化并且已经创建了浏览器窗口,则该方法将会被调用。// 有些API只能在该事件发生后才能被使用。
app.on('ready', createWindow);
// 当所有的窗口被关闭后退出应用
app.on('window-all-closed', () => {
// 对于OS X系统,应用和相应的菜单栏会一直激活直到用户通过Cmd + Q显式退出
if (process.platform !== 'darwin') {
app.quit();
}
});

app.on('activate', () => {
// 对于OS X系统,当dock图标被点击后会重新创建一个app窗口,并且不会有其他
// 窗口打开
if (win === null) {
createWindow();
}
});
// 在这个文件后面你可以直接包含你应用特定的由主进程运行的代码。// 也可以把这些代码放在另一个文件中然后在这里导入。

/*******************实现代码************************** */
//通信模块,mian process与renderer process(web page)
const {ipcMain} = require('electron')//监听web page里发出的message
let downloadpath;//下载路径
let savepath; //保存路径
ipcMain.on('download', (event, args) => {
var arr=args.split("+");
  downloadpath=arr[0];
savepath=arr[1];
  //下面这句会触发will-download事件
  win.webContents.downloadURL(downloadpath);
})
/*******************实现代码************************** */



gulpfile.js

// 获取依赖
var gulp = require('gulp'),
childProcess = require('child_process'),
electron = require('electron-prebuilt');
// 创建 gulp 任务
gulp.task('run', function () {
childProcess.spawn(electron, ['--debug=5858','.'], {stdio:'inherit'});
});

package.json

{
"name": "package.json",
"version": "1.4.0",
"description": "hello world",
"main": "app/main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "NS",
"license": "ISC",
"devDependencies": {
"electron-prebuilt": "^1.4.13",
"gulp": "^3.9.1"
}
}


测试:

【Electron】Electron下载功能实现

【Electron】Electron下载功能实现


注意:

1.ipcMain和ipcRender的传参问题

ipcMain/ipcRender.send(eventname, arg);

此处的arg是一个参数而不是参数数组。所以由于要传下载地址和文件存放地址,我选择使用“+”把它们连接起来。

2. 需要下载的文件地址是否正确

博主下载文件的地址应该是f:\\1\\1.txt

然后写成了f:\\1.txt 导致一直提示下载失败:interrupted

半个小时才找到问题,知道真相的我要死的心都有了,希望各位注意。