这就是我最爆炸的部分。完成这个应用的一半时间都贡献给了这部分。
先进行简单的校验
- button_download.addEventListener("click",
- function() {
- var tips = document.getElementsByClassName("tips")[0];
- if (downloadFolder.value != "" && downloadAddress.value != "") {
- //下载文件
- } else if (downloadAddress.value == "") {
- tips.innerText = "未填写下载地址";
- } else {
- tips.innerText = "未选择文件夹"
- }
- })
下载文件我使用的是will-download,寻找一个合适的模块实现真的很心累,这里就不赘述了。
由于will-download是主进程的模块调用的,所以此处就需要主进程和渲染进程的通信。
通信原理如下:
- // 后台进程
- const {ipcMain} = require('electron')
- ipcMain.on('create', (event, person) => {
- console.log('creating', person) // 输出:"creating harttle"
- event.sender.send('born', person)
- });
- // 渲染进程
- const {ipcRenderer} = require('electron')
- ipcRenderer.on('born', (event, person) => {
- console.log(person, 'born') // 输出 "harttle born"
- });
- ipcRenderer.send('create', 'harttle')
所以我的想法是,在主进程里监听一个download事件,在渲染进程里当点击下载时调用这个事件。
- //主进程代码
- ipcMain.on('download', (evt, args) = >{
- var arr = args.split("+");
- downloadpath = arr[0];
- folderpath = arr[1];
- evt.sender.send('tips', downloadpath);
- mainWindow.webContents.downloadURL(downloadpath);
- });
- //渲染器进程代码
- ipcRenderer.send('download', downloadAddress.value + "+" + downloadFolder.value);
下面这句会触发will-download事件
- mainWindow.webContents.downloadURL(downloadpath);
下面来设置监听will-download事件的回调函数
- mainWindow.webContents.session.on('will-download', (event, item, webContents) => {
- //设置文件存放位置
- item.setSavePath(folderpath+`\\${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')
- } else {
- console.log(`Download failed: ${state}`)
- }
- })
- })
其实我一开始使用的是ipc进行两个进程之间的通信,但是不论我怎么定义,ipc总是报错,报其没有send和on方法。
又疯狂找资料,遇到这个问题的人还真不多,所以没有找到解决方法。
但是后来发现,与主进程的通信可以使用ipcMain,所以就弃用ipc了。
找不到为什么错真的很伤自尊啊,希望下次可以发现。
这个的解决方法是退出应用然后重新npm start一次。
这个很好理解吧,重新刷新页面只是更新了渲染器进程而非主进程。
这个方法接受一个参数即文件存放路径。
但是!一定保证路径里包含了文件名!一定!
否则,就算路径不正确它也不会报错而是选择存放在默认路径下。
- ipcMain / ipcRender.send(eventname, arg);
此处的arg是一个参数而不是参数数组。
所以由于要传下载地址和文件存放地址,我选择使用“+”把它们连接起来。
来源: https://www.2cto.com/kf/201710/689654.html