Skip to content

Electron 原生功能与系统集成完全指南

前言

Electron 的强大之处在于能够访问系统级功能,让 Web 应用具备原生应用的能力。这篇文章将介绍 Electron 提供的各种原生功能和系统集成 API。

文件系统操作

文件对话框

javascript
// main.js
const { dialog } = require('electron')

ipcMain.handle('dialog:openFile', async () => {
  const { canceled, filePaths } = await dialog.showOpenDialog({
    title: '选择文件',
    defaultPath: app.getPath('documents'),
    buttonLabel: '打开',
    filters: [
      { name: '文本文件', extensions: ['txt', 'md'] },
      { name: '所有文件', extensions: ['*'] }
    ],
    properties: ['openFile', 'multiSelections']
  })

  if (!canceled) {
    return filePaths
  }
})

ipcMain.handle('dialog:saveFile', async () => {
  const { canceled, filePath } = await dialog.showSaveDialog({
    title: '保存文件',
    defaultPath: path.join(app.getPath('documents'), 'untitled.txt'),
    buttonLabel: '保存',
    filters: [
      { name: '文本文件', extensions: ['txt'] }
    ]
  })

  if (!canceled) {
    return filePath
  }
})

文件读写

javascript
// main.js
const fs = require('fs').promises

ipcMain.handle('file:read', async (event, filePath) => {
  try {
    const content = await fs.readFile(filePath, 'utf8')
    return { success: true, content }
  } catch (error) {
    return { success: false, error: error.message }
  }
})

ipcMain.handle('file:write', async (event, filePath, content) => {
  try {
    await fs.writeFile(filePath, content, 'utf8')
    return { success: true }
  } catch (error) {
    return { success: false, error: error.message }
  }
})

系统通知

javascript
// main.js
const { Notification } = require('electron')

ipcMain.handle('notification:show', (event, options) => {
  const notification = new Notification({
    title: options.title,
    body: options.body,
    icon: options.icon,
    silent: options.silent || false,
    urgency: options.urgency || 'normal',
    timeoutType: options.timeoutType || 'default'
  })

  notification.on('click', () => {
    mainWindow.show()
    mainWindow.focus()
  })

  notification.show()
})

// renderer.js
window.electronAPI.showNotification({
  title: '新消息',
  body: '你有一条新消息',
  icon: 'path/to/icon.png'
})

系统托盘

javascript
const { Tray, Menu, nativeImage } = require('electron')

let tray = null

function createTray() {
  const icon = nativeImage.createFromPath('path/to/icon.png')
  tray = new Tray(icon.resize({ width: 16, height: 16 }))

  const contextMenu = Menu.buildFromTemplate([
    {
      label: '显示窗口',
      click: () => mainWindow.show()
    },
    {
      label: '隐藏窗口',
      click: () => mainWindow.hide()
    },
    { type: 'separator' },
    {
      label: '退出',
      click: () => app.quit()
    }
  ])

  tray.setToolTip('My Application')
  tray.setContextMenu(contextMenu)

  tray.on('click', () => {
    mainWindow.isVisible() ? mainWindow.hide() : mainWindow.show()
  })
}

全局快捷键

javascript
const { globalShortcut } = require('electron')

app.whenReady().then(() => {
  // 注册全局快捷键
  globalShortcut.register('CommandOrControl+Shift+K', () => {
    mainWindow.webContents.toggleDevTools()
  })

  globalShortcut.register('CommandOrControl+Shift+H', () => {
    mainWindow.isVisible() ? mainWindow.hide() : mainWindow.show()
  })
})

app.on('will-quit', () => {
  // 注销所有快捷键
  globalShortcut.unregisterAll()
})

剪贴板操作

javascript
// main.js
const { clipboard } = require('electron')

ipcMain.handle('clipboard:writeText', (event, text) => {
  clipboard.writeText(text)
})

ipcMain.handle('clipboard:readText', () => {
  return clipboard.readText()
})

ipcMain.handle('clipboard:writeHTML', (event, html) => {
  clipboard.writeHTML(html)
})

系统信息获取

javascript
const { app, screen, powerMonitor } = require('electron')
const os = require('os')

ipcMain.handle('system:getInfo', () => {
  return {
    platform: process.platform,
    arch: process.arch,
    version: process.version,
    electron: process.versions.electron,
    chrome: process.versions.chrome,
    node: process.versions.node,
    cpus: os.cpus().length,
    totalMemory: os.totalmem(),
    freeMemory: os.freemem(),
    homeDir: os.homedir(),
    tmpDir: os.tmpdir(),
    username: os.userInfo().username,
    displays: screen.getAllDisplays()
  }
})

// 电源监控
powerMonitor.on('suspend', () => {
  console.log('系统休眠')
})

powerMonitor.on('resume', () => {
  console.log('系统恢复')
})

Shell 集成

javascript
const { shell } = require('electron')

ipcMain.handle('shell:openExternal', (event, url) => {
  return shell.openExternal(url)
})

ipcMain.handle('shell:openPath', (event, path) => {
  return shell.openPath(path)
})

ipcMain.handle('shell:showItemInFolder', (event, fullPath) => {
  shell.showItemInFolder(fullPath)
})

协议处理

javascript
const { app, protocol } = require('electron')

// 注册自定义协议
app.whenReady().then(() => {
  protocol.registerFileProtocol('myapp', (request, callback) => {
    const url = request.url.replace('myapp://', '')
    try {
      return callback(decodeURIComponent(url))
    } catch (error) {
      console.error(error)
    }
  })
})

// 设置为默认协议处理程序
if (process.defaultApp) {
  if (process.argv.length >= 2) {
    app.setAsDefaultProtocolClient('myapp', process.execPath, [path.resolve(process.argv[1])])
  }
} else {
  app.setAsDefaultProtocolClient('myapp')
}

总结

Electron 提供了丰富的原生 API,让 Web 应用能够深度集成系统功能。掌握这些 API,能够打造出真正的原生应用体验。


相关文章推荐: