Правильное использование open dialog в electron

Я пробую написать простенькую игру на js, используя electron и node js, но столкнулся с трудностями. При попытке запустить выбор файла(функция lol(), думаю название не важно) выдаёт ошибку: Uncaught TypeError: Cannot read properties of undefined (reading 'showOpenDialog'). Пробовал разные способы.

<!DOCTYPE html>
<html>
<head>
<script  type="text/javascript" src="main.js"></script>
<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
<title>Угадай мелодию</title> 
</head>
<body>
<p id="title">Test</p>
<button onclick="lol()">test</button>
</body> 
</html>
const { app, BrowserWindow,  dialog, remote}  = require('electron')
const path = require('path')
const child_process = require('child_process');
const { executionAsyncResource } = require('async_hooks');
var fs = require('fs');
const createWindow = () => {
  const mainWindow = new BrowserWindow({
    webPreferences: {
      nodeIntegration: true,
      enableremotemodule: true,
      contextIsolation: false,
      }
  })
  mainWindow.loadFile('main.html')
  //mainWindow.webContents.openDevTools()
}
app.whenReady().then(() => {
  createWindow()
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow()
  })
})
app.on('window-all-closed', () => {
  if (process.platform == 'darwin') app.quit()
})
function lol(){
    dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'] });   
}

Ответы (1 шт):

Автор решения: Neverm1ndo

Модуль remote, с помощью которого вы вызываете dialog из рендеринг процесса, в версии 14.0.0 был удален из стандартной поставки. Вместо него используйте ipc.

Вызвать диалоговое окно из рендеринг процесса можно так:

main.js

const { app, BrowserWindow,  dialog, ipcMain }  = require('electron');
const path = require('path')
const fs = require('fs');
const child_process = require('child_process');
const { executionAsyncResource } = require('async_hooks');

let mainWindow;


const createWindow = () => {
  mainWindow = new BrowserWindow({
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
    }
  });
  mainWindow.loadFile('main.html');
  //mainWindow.webContents.openDevTools()
}

app.whenReady().then(() => {
  createWindow();
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });
});

app.on('window-all-closed', () => {
  if (process.platform == 'darwin') app.quit();
});

/** Вернет Promise<Object> с результатом */
ipcMain.handle('open-dialog', (_event, options) => {
  return dialog.showOpenDialog(options); 
});

renderer.js

electron.ipcRenderer.send('open-dialog', { properties: ['openFile', 'multiSelections'] })
                    .then(result => {
                      console.log(result.canceled);
                      console.log(result.filePaths);
                    }).catch(err => {
                      console.log(err);
                    });

Документация по:

Все же, использовать устаревший и небезопасный remote никто не запрещает.

Для этого нужно импортировать модуль отдельно:

const { BrowserWindow } = require('@electron/remote')
require('@electron/remote/main').initialize()

Но лучше не надо.

→ Ссылка