Skip to content
On this page

electron-dl

一个用于在 Electron 应用程序中处理文件下载的工具

安装

bash
pnpm add electron-dl

基础配置

主进程配置

ts
import { app, BrowserWindow } from 'electron'
import { download } from 'electron-dl'

app.whenReady().then(() => {
  const mainWindow = new BrowserWindow({
    width: 900,
    height: 670,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
    },
  })

  // 监听下载请求
  mainWindow.webContents.session.on('will-download', (event, item, webContents) => {
    // 使用 electron-dl 处理下载
    download(mainWindow, item.getURL())
  })
})

使用示例

基本下载功能

ts
import { download } from 'electron-dl'

// 处理下载请求
async function handleDownload(window: BrowserWindow, url: string) {
  try {
    const dl = await download(window, url, {
      // 保存路径
      directory: app.getPath('downloads'),
      // 显示保存对话框
      showBadge: true,
      // 显示进度条
      showProgressBar: true,
    })

    console.log('下载完成:', dl.getSavePath())
  } catch (error) {
    console.error('下载失败:', error)
  }
}

// 使用示例
app.whenReady().then(() => {
  const mainWindow = new BrowserWindow()

  // 处理下载请求
  ipcMain.handle('download-file', async (event, url) => {
    return handleDownload(mainWindow, url)
  })
})

自定义下载配置

ts
import { download } from 'electron-dl'

// 配置下载选项
const downloadOptions = {
  // 自定义保存路径
  directory: app.getPath('downloads'),
  // 自定义文件名
  filename: 'custom-name.zip',
  // 显示保存对话框
  saveAs: true,
  // 打开文件选择器时的标题
  title: '选择保存位置',
  // 下载进度回调
  onProgress: (progress) => {
    console.log('下载进度:', progress.percent, '速度:', progress.transferredBytes, '/', progress.totalBytes)
  },
}

// 执行下载
download(mainWindow, fileUrl, downloadOptions)

高级配置

ts
import { app, BrowserWindow, dialog } from 'electron'
import { download } from 'electron-dl'

app.whenReady().then(() => {
  const mainWindow = new BrowserWindow()

  // 高级下载管理
  class DownloadManager {
    private window: BrowserWindow
    private downloads: Map<string, any>

    constructor(window: BrowserWindow) {
      this.window = window
      this.downloads = new Map()

      // 监听所有下载请求
      this.window.webContents.session.on('will-download', this.handleDownload.bind(this))
    }

    private async handleDownload(event: Event, item: Electron.DownloadItem, webContents: Electron.WebContents) {
      const url = item.getURL()

      try {
        // 询问用户是否下载
        const { response } = await dialog.showMessageBox(this.window, {
          type: 'question',
          buttons: ['下载', '取消'],
          message: '是否下载文件?',
          detail: `文件: ${item.getFilename()}\n大小: ${(item.getTotalBytes() / 1024 / 1024).toFixed(2)} MB`,
        })

        if (response === 1) {
          item.cancel()
          return
        }

        // 开始下载
        const dl = await download(this.window, url, {
          directory: app.getPath('downloads'),
          filename: item.getFilename(),
          saveAs: true,
          // 下载开始回调
          onStarted: (downloadItem) => {
            this.downloads.set(url, downloadItem)
            console.log('开始下载:', downloadItem.getFilename())
          },
          // 下载进度回调
          onProgress: (progress) => {
            const percent = progress.percent
            const speed = (progress.transferredBytes / 1024 / 1024).toFixed(2)
            console.log(`下载进度: ${percent}%, 速度: ${speed} MB/s`)

            // 更新任务栏进度
            this.window.setProgressBar(percent / 100)
          },
          // 下载完成回调
          onCompleted: (file) => {
            this.downloads.delete(url)
            this.window.setProgressBar(-1)
            console.log('下载完成:', file)

            dialog.showMessageBox(this.window, {
              type: 'info',
              message: '下载完成',
              detail: `文件已保存至: ${file}`,
            })
          },
        })
      } catch (error) {
        console.error('下载失败:', error)
        dialog.showErrorBox('下载失败', error.message)
      }
    }

    // 暂停下载
    pauseDownload(url: string) {
      const download = this.downloads.get(url)
      if (download) {
        download.pause()
      }
    }

    // 恢复下载
    resumeDownload(url: string) {
      const download = this.downloads.get(url)
      if (download) {
        download.resume()
      }
    }

    // 取消下载
    cancelDownload(url: string) {
      const download = this.downloads.get(url)
      if (download) {
        download.cancel()
        this.downloads.delete(url)
      }
    }
  }

  // 创建下载管理器实例
  const downloadManager = new DownloadManager(mainWindow)

  // 暴露下载管理接口到渲染进程
  ipcMain.handle('download-file', async (event, url) => {
    return download(mainWindow, url)
  })

  ipcMain.handle('pause-download', (event, url) => {
    downloadManager.pauseDownload(url)
  })

  ipcMain.handle('resume-download', (event, url) => {
    downloadManager.resumeDownload(url)
  })

  ipcMain.handle('cancel-download', (event, url) => {
    downloadManager.cancelDownload(url)
  })
})

要保持清醒 永远不抱有意外的幻想 凭空的期待最要命