【Electron】实现下载、上传、系统提示功能(dialog模块)

本文介绍了如何利用Electron的dialog模块实现应用的下载、上传和系统提示功能。通过对话框,用户可以选择文件进行下载和上传操作,并且展示了在不同操作系统中使用dialog模块时的注意事项和参数解释。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前言

本文主要介绍electron应用的dialog模块的适用场景,主要包括下载保存、文件上传、消息提示等场景。其中上传下载配合使用node的request模块。

二、实施内容

1.实现下载功能

这里我们主要用到的是electron的dialog模块中的showSaveDialog方法。主要实现方式如下,这里我们创建一个ElectronDownloadFile.js文件,用于封装下载方法

import { ipcMain, dialog } from 'electron'
import path from 'path'
const fs = require('fs')
const request = require('request')
let _win // 当前窗口实例
let isMac = process.platform === 'darwin' // 判断是否为macOS

export function downloadFile (win) {// 解决M1芯片可能会报证书失效问题process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'_win = win// 创建监听事件,接收来自渲染进程的下载请求// file参数为一个对象{name: '文件名,例***.jpg', url: '文件远端路径'}ipcMain.on('downloadFile', (event, file) => {/*为解决文件名包含特殊字符引起无发下载 --- start */var reg = /\\|\/|\?|\?|\*|\"|\“|\”|\'|\‘|\’|\<|\>|\{|\}|\[|\]|\[|\]|\:|\:|\^|\$|\!|\~|\`|\|/gconst fileNameSplitArr = file.name.split('/')fileNameSplitArr[fileNameSplitArr.length - 1] = fileNameSplitArr[fileNameSplitArr.length - 1].replace(reg, '')file.name = fileNameSplitArr.join('')/*为解决文件名包含特殊字符引起无发下载 --- end */// 这里设置了保存弹出框的默认名称(如下图1),设置openDirectory表示可以选择文件夹dialog.showSaveDialog(win, { defaultPath: file.name, properties: ['openDirectory'] }).then(result => {// 承载文件源地址const fileURL = file.url// 这里获取用户通过弹框做选择的保存至本地的地址if (result.filePath.length !== 0) {let localPath = result.filePathif (!isMac) { // 处理windows系统反斜杠问题const arr = localPath.split(path.sep)localPath = arr.reduce((pre, cue) => {return pre ? `${pre}//${cue}` : cue}, '')}// 最终处理好写入本地文件路径,去下载了toDownloadFile(fileURL, localPath)}}).catch(err => {console.log(err)})})
}

const toDownloadFile (file_url, targetPath) => {var received_bytes = 0 // 当前下载量var total_bytes = 0 // 文件总大小var req = request({method: 'GET',uri: file_url,strictSSL: false,rejectUnauthorized: false}) // 下载中命名后加:.download,提示用户未下完var out = fs.createWriteStream(targetPath + '.download')req.pipe(out)req.on('response', (data) => {// 获取文件大小total_bytes = parseInt(data.headers['content-length'])})req.on('data', (chunk) => {// 更新下载进度received_bytes += chunk.lengthshowProgress(received_bytes, total_bytes, file_url)})// 下载完成req.on('end', () => {const oldPath = targetPath + '.download'if (_win) { // 判断当前窗口实例存在// 异步改名,如果异常则e有值,抛出downloaded_rename_error,在Home.vue处理,fs.rename(oldPath, targetPath, (e) => {if (!e) {// eslint-disable-next-line camelcase_win.webContents.send('downloaded' + file_url, targetPath)} else {_win.webContents.send('downloaded_rename_error', e, targetPath)}})}})
}

const showProgress (received, total, file_url) => {var percentage = (received * 100) / totalif (_win) {// 更新下载进度给渲染进程, 这里注意加上file_url为了防止,多个文件同时下载,让渲染进程进行分辨的,只监听自己的下载进度_win.webContents.send('download-progress' + file_url, percentage)}
} 

图1

之后我们将这个文件在主进程中引入即可

import { downloadFile } from '
Electron 中,你可以通过 Node.js 的 `webContents` 对象来创建并显示对话框,这个对象通常在渲染进程中作为 `window.webContents` 存储在 BrowserWindow 实例中。要在子窗口(Child Window)中弹出对话框,你需要做以下步骤: 1. 首先,确保你的子窗口有一个 `webContents` 可用。这通常是通过创建一个新的 BrowserWindow 实例获得的。 ```javascript const { BrowserWindow } = require('electron'); const childWindow = new BrowserWindow(); ``` 2. 然后,当你想在子窗口中打开一个对话框时,可以使用 `webContents.send` 方法发送一个消息到子窗口,告诉它去显示一个对话框。例如,你可以创建一个全局函数来处理这个操作: ```javascript global.showDialogInChildWindow = function(message) { childWindow.webContents.send('show-dialog', message); }; ``` 3. 在子窗口的 `event.sender` 检测到 'show-dialog' 事件时,它会触发对应的回调函数来显示对话框。在主进程(main process)中,需要监听这个事件并调用相应的 API,比如 `dialog` 或者 `shell` 对象: ```javascript // 主进程中 childWindow.on('message', (event, data) => { if (event === 'show-dialog') { const dialogOptions = { type: data.type, // 指定对话框类型,如 'question', 'alert', 'prompt' message: data.message, // 提示信息 buttons: data.buttons, // 按钮数组 defaultId: data.defaultId // 默认按钮索引 }; dialog.showMessageBox(childWindow.webContents, dialogOptions); } }); ``` 4. 最后,在子窗口中,你需要监听来自主进程的消息,并准备显示对话框: ```javascript // 子窗口中的事件处理器 webContents.addEventListener('ipc-message', (event, arg) => { switch (arg.eventName) { case 'show-dialog': console.log('Showing dialog with options:', arg.options); break; // ...其他处理逻辑... } }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值