pglezen
pglezen

Reputation: 1021

Electron dialog undefined in contextBridge

Platform

Description

I'm trying to display a file dialog from an Electron renderer process. I thought I could reference the dialog object in the same way I reference ipcRenderer through the contextBridge.

// preload.ts

const { contextBridge, ipcRenderer, dialog } = require('electron');
import type { IpcRendererEvent } from 'electron';

contextBridge.exposeInMainWorld(
  'ipc',
  {
    send: (channel: string, data: string[]) => {
      ipcRenderer.send(channel, data);
    },
    on: (channel: string, func: (evt: IpcRendererEvent, args: any) => void) => {
      ipcRenderer.on(channel, func);
    },
    chooseFile: (title: string) => dialog.showOpenDialogSync({
      title, properties: ['openFile']})
  }
)

But when I invoke window.ipc.chooseFile('Some Title'), I receive an error:

Cannot read property 'showOpenDialogSync' of undefined

This seems to indicate that the dialog reference is not conveyed through the contextBridge proxy. Yet the first two functions that convey ipcRenderer work. The exposeInMainWorld documentation warns us that not every type can be proxied.

Notes

  1. I understand that the generality of the three functions in my example undermines the security purpose of context isolation. I'm just trying to determine what works before I invest too much time designing a detailed message passing scheme.

  2. I understand I can implement this function in the main process and invoked it through IPC. I'm fine with that. I'm just curious why an ipcRenderer reference is successfully proxied through the contextBridge but dialog is not.

Upvotes: 3

Views: 1030

Answers (1)

kdau
kdau

Reputation: 2099

The issue isn't one of proxying through the contextBridge, but one of which Electron APIs are available in the renderer process at all. Unfortunately dialog just isn't one of those (note "Process: Main" on its page), so it can't be referenced directly in the renderer process, even during preload. The old remote API for using main process modules from the renderer process is still available, but it rightly warns you that

The remote module is deprecated. Instead of remote, use ipcRenderer and ipcMain.

So yes, your solution in note (2) is the intended one.

Upvotes: 3

Related Questions