常用的 electronAPI 方法

1 ipcRenderer 方法

ipcRenderer 是最常用的功能,用于渲染进程和主进程之间的通信。

方法用途
ipcRenderer.send(channel, …args)向主进程发送异步消息
ipcRenderer.invoke(channel, …args)通过异步调用向主进程请求数据,并返回 Promise
ipcRenderer.on(channel, listener)监听主进程发来的消息
ipcRenderer.once(channel, listener)只监听一次主进程的消息,触发后自动移除监听器
ipcRenderer.removeAllListeners(channel)移除指定频道的所有监听器

React 使用示例

示例一: 通过ipcRenderer.send 实现通信
写了一个按钮,点击发送给主进程,send接收两个参数,第一个是通信通道的名称要和主进程的名称相同,第二个是要传递的数据

 const [count, setCount] = useState(0)

  const handlesubmit = (): void => {
    window.electron.ipcRenderer.send('tong_01', count)
  }

在electron的主进程中接收,通过ipcMain.on的方式,这里也是接收两个参数,第一个是通信名称,第二个回调函数,回调函数的参数第一个是事件,第二个就是渲染进程传递而来的数据,通过 event.reply可以把数据传递到指定的通道中

  ipcMain.on('tong_01', (event, arg) => {
    const item = arg + 1
    console.log(item)
    event.reply('reply_01', item)
  })

回到组件,如果是通过on监听,每当event.reply(‘reply_01’, item)主进程往reply_01传递数据,ipcRenderer.on就会触发并且拿到数据

  window.electron.ipcRenderer.on('reply_01', (_event: unknown, res: number) => {
        console.log(res)
        setCount(res)
      })

通过ipcRenderer.once监听,和on一样,但是once监听一次之后就会自动销毁

 window.electron.ipcRenderer.once('reply_01', (_event: unknown, res: number) => {
        console.log(res)
        setCount(res)
      })

如果采用的是ipcRenderer.on需要在组件销毁的时候关闭监听,这里是React,在useEffect的return中销毁

return (): void => {
      window.electron.ipcRenderer.removeAllListeners('reply_01')
    }

示例一: 通过ipcRenderer.invoke实现通信
在渲染进程中通过ipcRenderer.invoke指定通道发送数据,返回一个promise,通过await拿到promise的返回值 进行操作

 const handlesubmit = async (): Promise<void> => {
    const res = await window.electron.ipcRenderer.invoke('tong_01', count)
    setCount(res)
  }

在主进程中通过ipcMain.handle生产这个通道,ipcMain.handle和ipcRenderer.invoke结合async、await使用可以实现优雅的主进程和渲染进程之间的通信

  ipcMain.handle('tong_01', (event, arg) => {
    const item = arg + 1
    console.log(item) // 打印处理结果
    return item // 返回处理结果给渲染进程
  })

什么时候使用 send + reply,什么时候使用 invoke + handle?

  • 使用 send + reply 适合的场景:
    • 不需要获取返回值:如果渲染进程只需要发送消息到主进程,不需要等待主进程返回数据,可以使用 send 和 reply。
    • 事件驱动的场景:如果需要监听同一个通道的多个事件,或需要在主进程做一些长期的处理并通知多个渲染进程,send + reply 更加合适。
    • 性能要求较低的简单任务:对于一些简单的任务,直接用 send + reply 的方式已经足够。
  • 使用 invoke + handle 适合的场景:
    • 需要获取返回值:当渲染进程需要等待主进程的计算结果(如数据库查询、文件读取等)时,invoke 更适合,因为它提供了一个 Promise 来等待异步操作的结果。
    • 代码清晰简洁:invoke 和 handle 使得代码更加直观,尤其是与 async/await 一起使用时,能够减少回调函数的嵌套,增强可读性。
      避免重复事件监听:如果不希望渲染进程重复注册事件监听器,invoke 也能帮助避免事件监听器的多次注册问题。

2 shell 方法

shell 模块允许渲染进程调用外部程序或操作文件。 最新的electron已经不支持这种写法了,但是shell模块依然存在,通过ipcRenderer方法通知主线程之后,在主线程之中调用shell模块

方法用途
shell.openExternal(url)在默认浏览器中打开一个 URL
shell.openPath(path)打开指定的文件或文件夹
shell.trashItem(path)将指定文件移到回收站
shell.showItemInFolder(fullPath)在文件管理器中显示文件

React 使用示例
下面是一个React组件,包含4个按钮

function Shell(): JSX.Element {
  const handeleExternal = (): void => {
    window.electron.ipcRenderer.send('open_external', 'https://www.baidu.com')
  }

  const handelePath = (): void => {
    window.electron.ipcRenderer.send('open_path', 'C:/111')
  }
  const handeleDel = (): void => {
    window.electron.ipcRenderer.send('del_path', 'C:\\111\\444.txt')
  }
  const handeleShow = (): void => {
    window.electron.ipcRenderer.send('open_show', 'C:\\111\\333')
  }
  return (
    <>
      <h1>Shell</h1>
      <div>
        <button onClick={handeleExternal}> shell.openExternal </button>
        <p> 在默认浏览器中打开一个 URL (&apos;https://www.baidu.com&apos;)</p>
      </div>
      <div>
        <button onClick={handelePath}> shell.openPath </button>
        <p> 打开指定文件夹,后续通过其他方法获取当前文件夹打开,也可以编写一个输入框进行</p>
      </div>
      <div>
        <button onClick={handeleDel}> shell.trashItem </button>
        <p> 删除文件或者文件夹,删除文件要把后缀补全 </p>
      </div>
      <div>
        <button onClick={handeleShow}> shell.showItemInFolder </button>
        <p> 打开并且高亮文件或者文件夹,高亮文件需要把后缀补全</p>
      </div>
    </>
  )
}

export default Shell

在这里插入图片描述

shell.openExterna

渲染线程

const handeleExternal = (): void => {
    window.electron.ipcRenderer.send('open_external', 'https://www.baidu.com')
  }

主线程

 ipcMain.on('open_external', (_event, arg) => {
    console.log(arg)
    // event.reply('reply_01', item)
    shell
      .openExternal(arg)
      .then(() => {
        console.log('ok')
      })
      .catch((_err) => console.log('err'))
  })

shell.openPath

渲染线程

 const handelePath = (): void => {
    window.electron.ipcRenderer.send('open_path', 'C:/111')
  }

主线程



ipcMain.on('open_path', (_event, arg) => {
    shell
      .openPath(arg)
      .then(() => {
        console.log('ok')
      })
      .catch((_err) => console.log('err'))
  })

shell.trashItem

渲染线程

  const handeleDel = (): void => {
    window.electron.ipcRenderer.send('del_path', 'C:\\111\\444.txt')
  }

主线程

   // 引入path模块 使用path.normalize确保路劲万无一失
  const path = require('path')
  ipcMain.on('del_path', (_event, arg) => {
    const folderPath = path.normalize(arg)
    console.log(folderPath)
    // event.reply('reply_01', item)

    shell
      .trashItem(folderPath)

      .then(() => {
        console.log('ok')
      })
      .catch((_err) => console.log(_err))
  })

shell.showItemInFolder

渲染线程

  const handeleShow = (): void => {
    window.electron.ipcRenderer.send('open_show', 'C:\\111\\333')
  }

主线程

 ipcMain.on('open_show', (_event, arg) => {
    const folderPath = path.normalize(arg)
    console.log(folderPath)
    shell.showItemInFolder(folderPath)
  })

3 clipboard 方法

clipboard 模块允许操作系统剪贴板。

方法用途
clipboard.writeText(text)将文本写入剪贴板
clipboard.readText()从剪贴板读取文本
clipboard.writeImage(image)将图片写入剪贴板
clipboard.readImage()从剪贴板读取图片

这个模板的’electron没有默认导出clipboard,需要直接去preload的index文件中添加
在这里插入图片描述
除此之外,ts会出现类型检查的错误,需要去接口的文件添加
在这里插入图片描述

React 使用示例

![function Clip(): JSX.Element {
  const handelewriteText = (): void => {
    console.log('向粘贴板存内容')
    window.electron.clipboard.writeText('Hello, Clipboard!2')
  }

  const handeleRead = (): void => {
    const txt = window.electron.clipboard.readText()
    console.log('读取粘贴板的内容', txt)
  }

  return (
    <>
      <h1>Shell</h1>
      <div>
        <button onClick={handelewriteText}> clipboard.writeText </button>
        <p> 往粘贴板里放文本 </p>
      </div>
      <div>
        <button onClick={handeleRead}> clipboard.readText </button>
        <p> 读取粘贴板的文本</p>
      </div>
    </>
  )
}

export default Clip


在这里插入图片描述

4 dialog 方法

dialog 用于显示对话框。

方法用途
dialog.showOpenDialog(options)显示文件或文件夹选择对话框
dialog.showSaveDialog(options)显示保存文件对话框
dialog.showMessageBox(options)显示消息对话框
dialog.showErrorBox(title, content)显示错误对话框

React 使用示例

const openFile = async () => {
  const result = await window.electron.dialog.showOpenDialog({
    properties: ['openFile', 'multiSelections'],
  });
  console.log('Selected files:', result.filePaths);
};

5 自定义 electronAPI

开发者可以在 preload.js 中添加自定义方法并暴露给渲染进程。

preload.js 示例

const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('electron', {
  ipcRenderer: {
    send: (channel, ...args) => ipcRenderer.send(channel, ...args),
    invoke: (channel, ...args) => ipcRenderer.invoke(channel, ...args),
    on: (channel, listener) => ipcRenderer.on(channel, listener),
  },
  customApi: {
    getAppVersion: () => ipcRenderer.invoke('get-app-version'),
  },
});

React 使用自定义方法

const getAppVersion = async () => {
  const version = await window.electron.customApi.getAppVersion();
  console.log('App version:', version);
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值