电子 v10.1.1 给出未捕获的类型错误:无法读取未定义的属性“对话框”,但相同的代码在电子 v9.3.0 中有效

Was*_*tab 7 javascript electron

我正在尝试在电子应用程序中上传一个文件,该文件非常适用于电子 v9.3.0,但是一旦我使用电子 v10.1.1,它就会Uncaught TypeError: Cannot read property 'dialog' of undefined在这一行出现以下错误 ,const dialog = electron.remote.dialog;请参见下面的屏幕截图。 在此处输入图片说明

main.js 的内容如下

const { app, BrowserWindow } = require('electron') 

function createWindow () { 
// Create the browser window. 
const win = new BrowserWindow({ 
    width: 800, 
    height: 600, 
    webPreferences: { 
    nodeIntegration: true
    } 
}) 

// Load the index.html of the app. 
win.loadFile('src/index.html') 

// Open the DevTools. 
win.webContents.openDevTools() 
} 

// This method will be called when Electron has finished 
// initialization and is ready to create browser windows. 
// Some APIs can only be used after this event occurs. 
// This method is equivalent to 'app.on('ready', function())' 
app.whenReady().then(createWindow) 

// Quit when all windows are closed. 
app.on('window-all-closed', () => { 
// On macOS it is common for applications and their menu bar 
// To stay active until the user quits explicitly with Cmd + Q 
if (process.platform !== 'darwin') { 
    app.quit() 
} 
}) 

app.on('activate', () => { 
// On macOS it's common to re-create a window in the 
// app when the dock icon is clicked and there are no 
// other windows open. 
if (BrowserWindow.getAllWindows().length === 0) { 
    createWindow() 
} 
}) 

// In this file, you can include the rest of your 
// app's specific main process code. You can also 
// put them in separate files and require them here. 
Run Code Online (Sandbox Code Playgroud)

index.js 的内容如下

const electron = require('electron'); 
const path = require('path'); 

// Importing dialog module using remote 
const dialog = electron.remote.dialog;

var uploadFile = document.getElementById('upload'); 

// Defining a Global file path Variable to store 
// user-selected file 
global.filepath = undefined; 

uploadFile.addEventListener('click', () => { 
// If the platform is 'win32' or 'Linux' 
    if (process.platform !== 'darwin') { 
        // Resolves to a Promise<Object> 
        dialog.showOpenDialog({ 
            title: 'Select the File to be uploaded', 
            defaultPath: path.join(__dirname, '../assets/'), 
            buttonLabel: 'Upload', 
            // Restricting the user to only Text Files. 
            filters: [ 
                { 
                    name: 'Text Files', 
                    extensions: ['txt', 'docx'] 
                }, ], 
            // Specifying the File Selector Property 
            properties: ['openFile'] 
        }).then(file => { 
            // Stating whether dialog operation was 
            // cancelled or not. 
            console.log(file.canceled); 
            if (!file.canceled) { 
            // Updating the GLOBAL filepath variable 
            // to user-selected file. 
            global.filepath = file.filePaths[0].toString(); 
            console.log(global.filepath); 
            } 
        }).catch(err => { 
            console.log(err) 
        }); 
    } 
    else { 
        // If the platform is 'darwin' (macOS) 
        dialog.showOpenDialog({ 
            title: 'Select the File to be uploaded', 
            defaultPath: path.join(__dirname, '../assets/'), 
            buttonLabel: 'Upload', 
            filters: [ 
                { 
                    name: 'Text Files', 
                    extensions: ['txt', 'docx'] 
                }, ], 
            // Specifying the File Selector and Directory 
            // Selector Property In macOS 
            properties: ['openFile', 'openDirectory'] 
        }).then(file => { 
            console.log(file.canceled); 
            if (!file.canceled) { 
            global.filepath = file.filePaths[0].toString(); 
            console.log(global.filepath); 
            } 
        }).catch(err => { 
            console.log(err) 
        }); 
    } 
}); 
Run Code Online (Sandbox Code Playgroud)

index.html 的内容如下

<!DOCTYPE html> 
<html> 
<head> 
    <meta charset="UTF-8"> 
    <title>Hello World!</title> 
    <!-- https://electronjs.org/docs/tutorial 
                        /security#csp-meta-tag -->
    <meta http-equiv="Content-Security-Policy"
        content="script-src 'self' 'unsafe-inline';" /> 
</head> 
<body> 
    <h1>Hello World!</h1> We are using node 
    <script> 
        document.write(process.versions.node) 
    </script>, Chrome 
    <script> 
        document.write(process.versions.chrome) 
    </script>, and Electron 
    <script> 
        document.write(process.versions.electron) 
    </script>. 

    <h3>File Upload in Electron</h3> 
    <button id="upload">Upload File</button> 
    
    <!-- Adding Individual Renderer Process JS File -->
    <script src="index.js"></script> 
</body> 
</html> 
Run Code Online (Sandbox Code Playgroud)

tpi*_*chu 8

const win = new BrowserWindow({ 
    width: 800, 
    height: 600, 
    webPreferences: { 
         enableRemoteModule: true,
         nodeIntegration: true
    } 
}) 
Run Code Online (Sandbox Code Playgroud)

为了访问remote渲染器进程上的模块。我们需要启用enableRemoteModuletrue因为这是false较新版本的默认设置。

  • 即使使用您的解决方案,“电子.远程”也未定义 (2认同)

Dia*_*rdu 7

适用于 Electron 11.0 及以上版本

远程模块已被弃用。这意味着更新文件所需的对话框对象无法从渲染器 javascript 文件访问(例如index.js在本文中)。对话框对象仍然可以从主入口点访问。为了解决这个问题,您可以使用ipcMainipcRenderer对象来管理入口点和渲染器 JavaScript 代码之间的通信。

main.js- 或应用程序中使用的入口点 - 添加以下内容:

const {app, BrowserWindow, dialog, ipcMain } = require('electron')

// *** REST OF YOUR CODE GOES HERE *** 

ipcMain.on('file-request', (event) => {  
  // If the platform is 'win32' or 'Linux'
  if (process.platform !== 'darwin') {
    // Resolves to a Promise<Object>
    dialog.showOpenDialog({
      title: 'Select the File to be uploaded',
      defaultPath: path.join(__dirname, '../assets/'),
      buttonLabel: 'Upload',
      // Restricting the user to only Text Files.
      filters: [ 
      { 
         name: 'Text Files', 
         extensions: ['txt', 'docx'] 
      }, ],
      // Specifying the File Selector Property
      properties: ['openFile']
    }).then(file => {
      // Stating whether dialog operation was
      // cancelled or not.
      console.log(file.canceled);
      if (!file.canceled) {
        const filepath = file.filePaths[0].toString();
        console.log(filepath);
        event.reply('file', filepath);
      }  
    }).catch(err => {
      console.log(err)
    });
  }
  else {
    // If the platform is 'darwin' (macOS)
    dialog.showOpenDialog({
      title: 'Select the File to be uploaded',
      defaultPath: path.join(__dirname, '../assets/'),
      buttonLabel: 'Upload',
      filters: [ 
      { 
         name: 'Text Files', 
         extensions: ['txt', 'docx'] 
      }, ],
      // Specifying the File Selector and Directory 
      // Selector Property In macOS
      properties: ['openFile', 'openDirectory']
    }).then(file => {
      console.log(file.canceled);
      if (!file.canceled) {
      const filepath = file.filePaths[0].toString();
      console.log(filepath);
      event.send('file', filepath);
    }  
  }).catch(err => {
      console.log(err)
    });
  }
});
Run Code Online (Sandbox Code Playgroud)

将您的代码替换index.js为:

const { ipcRenderer } = require('electron');
var uploadFile = document.getElementById('upload');

//upon clicking upload file, request the file from the main process
uploadFile.addEventListener('click', () => {
  ipcRenderer.send('file-request');
});

//upon receiving a file, process accordingly
ipcRenderer.on('file', (event, file) => {
  console.log('obtained file from main process: ' + file);
});
Run Code Online (Sandbox Code Playgroud)

注意:我正在使用异步事件。ipcRenderer.sendSync这可以通过使用和处理返回值来实现同步- 请查看电子文档以获取更多信息。两者之间的区别在于,这sendSync是一个同步承诺:它会阻塞窗口,直到 发出返回值ipcMain。对于这样的过程来说,这似乎是理想的,因为我们可能希望窗口等待文件上传,直到允许用户继续交互。我没有这样做,因为:

  • 如果处理不当,它会阻止整个应用程序,如电子文档中所述
  • 即使应用程序在 上被阻止sendSync,按钮点击也会被处理。一旦文件对话框关闭,应用程序将触发所有已点击的响应,因此阻塞没有那么有用。
  • 通过使用简单的 bool 并管理选项,可以管理渲染器 javascript 上的对话是否打开cancel- 如果有人需要它,我们很乐意提供它!


小智 5

正如@tpikatchu所说:

const win = new BrowserWindow({ 
    width: 800, 
    height: 600, 
    webPreferences: { 
         enableremotemodule: true,
         nodeIntegration: true
    } 
})
Run Code Online (Sandbox Code Playgroud)

enableremotemodule: true
必须是驼峰式:enableRemoteModule: true

参考:https : //www.electronjs.org/docs/api/browser-window

ps:很抱歉创建新答案,但我还不能发表评论。