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)
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
enableRemoteModule: true,
nodeIntegration: true
}
})
Run Code Online (Sandbox Code Playgroud)
为了访问remote渲染器进程上的模块。我们需要启用enableRemoteModule,true因为这是false较新版本的默认设置。
适用于 Electron 11.0 及以上版本
远程模块已被弃用。这意味着更新文件所需的对话框对象无法从渲染器 javascript 文件访问(例如index.js在本文中)。对话框对象仍然可以从主入口点访问。为了解决这个问题,您可以使用ipcMain和ipcRenderer对象来管理入口点和渲染器 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,按钮点击也会被处理。一旦文件对话框关闭,应用程序将触发所有已点击的响应,因此阻塞没有那么有用。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:很抱歉创建新答案,但我还不能发表评论。