Open7
Electronのメインプロセスとレンダラープロセスの間のプロセス間通信について
Electronでは表示部分のレンダラープロセス,アプリの構築やアプリ内での様々な操作に関してはメインプロセスに分けられており,レンダラーでのイベントをもとに様々な高度な操作を行いたい場合,メインプロセスへデータを渡してメインプロセス内で実行した結果をレンダラープロセスに再び渡すことで結果を反映させることができる.
キーワード: ipcMain
, ipcRenderer
, contextBridge
表示画面のボタンを押すとファイル選択画面が開き,選択したファイル名を表示するプログラムの作成
これはレンダラー→メイン→レンダラーのような通信
renderer.js
const btn = document.getElementById('btn')
btn.addEventListner('click', async () => {
const filePath = await window.openFile()
}
contextBridge
によってメインプロセスとレンダラープロセス間のAPI等を定義する.
preload.js
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI',{
openFile: () => ipcRenderer.invoke('dialog:openFile')
})
渡された文字列がレンダラーで呼び出す際のAPIキーになる……?'electronAPI'
としているのは不明,ドキュメントでは'electron'
としている.
-
contextBridge.exposeInMainWorld(apiKey, api)
-
apiKey
:string
-
api
:any
---any
だがAPIの定義をここに記述する.
-
main.js
const {app, BrowserWindow, ipcMain, dialog} = require('electron')
const path = require('path')
async function handleFileOpen() {
const { canceled, filePaths } = await dialog.showOpenDialog()
if (canceled) {
return
} else {
return filePaths[0]
}
}
function createWindow () {
//...
}
app.whenReady().then(() => {
ipcMain.handle('dialog:openFile', handleFileOpen)
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
//...
-
dialog.showOpenDialog()
:Promise<Object>
ファイルを開く際のダイアログボックスを呼び出す.- returns
Promise<Obhect>
-
canceled
:boolean
ダイアログでキャンセルをされたかどうか -
filePaths
:string[]
選択したファイルのパス(複数可)
-
-
ipcMain.handle(channel: string, listner: Function<Promise<void> | any>)
-
ipcRenderer.invoke(channel, ...args)
がレンダラープロセスにおいて呼び出された際に呼び出すハンドラをメインプロセスに追加する.
-
- returns
ひとまずまとめ:
- 描画以外の操作(ファイル操作等)を行うのはメインプロセス
- レンダラープロセスから描画以外の操作を呼び出すために,プロセス間通信を行う.
- メインプロセスとレンダラープロセス間を結ぶのがAPI
- これは
contextBridge.exposeInMainWorld()
で定義する
- これは
- レンダラープロセス側は
ipcRenderer.invoke()
- メインプロセス側は
ipcMain.handle()
- メインプロセスとレンダラープロセス間を結ぶのがAPI
ここからメニューバーからファイル選択のダイアログ等を呼び出し,ファイル名を描画する際の流れ