这个下载功能本来是用于让用户下载应用安装包实现版本更新,electron-updater
需要应用正式的签名,因此以此方式实现。但存在用户使用防火墙禁用应用的联网功能,导致这个方法也不行,后来直接shell.openExternal('使用浏览器打开的路径')
让用户直接打开官网或下载链接算了(甩锅)
发起下载
let savePath
// 项目从electron4过渡到electron7,所以希望两边都保留
let electronVersion = process.versions.electron.split('.')[0]
// 渲染进程调起 选择保存路径
ipcMain.on('downloadFile', (event, downloadPath) => {
let currentWin = BrowserWindow.fromWebContents(event.sender)
const options = {
title: '保存至',
properties: ['openDirectory'] // 本希望只能够选中文件夹,不过在mac上还是会选中文件,这块我没做好
}
if (global.electronVersion >= 7) {
// 7.x
dialog.showSaveDialog(currentWin, options).then(res => {
if (res.canceled) return
savePath = path.dirname(res.filePath)
// 使用electron提供的下载方式
currentWin.webContents.downloadURL('下载路径')
})
} else {
// 4.x
dialog.showSaveDialog(currentWin, options, filePath => {
if (!filePath) return false
savePath = path.dirname(filePath)
currentWin.webContents.downloadURL('下载路径')
})
}
})
监听下载
const { BrowserWindow, shell, ipcMain } from 'electron'
let win = new BrowserWindow(...)
win.webContents.session.on('will-download', (event, item, webContents) => {
// 设置保存的路径(savePath为上面获取到的路径)
item.setSavePath(path.join(savePath, item.getFilename()))
// 下载信息更新
item.on('updated', (event, state) => {
if (state === 'interrupted') {
// 下载中断
} else if (state === 'progressing') {
if (item.isPaused()) { // 下载停止
// 等待渲染进程请求继续
ipcMain.once('resume', (event) => {
if (item.canResume()) { // 判断是否可以继续
item.resume()
} else {
event.sender.send('resumeCallback', 'cannot resume')
}
})
} else {
// 进度 百分数的整数
let progress = Math.floor(item.getReceivedBytes() / item.getTotalBytes() * 100)
win.webContents.send('progress', progress)
}
}
})
item.once('done', (event, state) => {
if (state === 'completed') {
console.log('download complete')
console.log(item.getSavePath())
// 打开下载后所在的文件夹
// shell.showItemInFolder(item.getSavePath())
// 以系统默认方式打开
shell.openItem(item.getSavePath())
} else {
console.log('downstate', state)
}
})
})