首页 > 解决方案 > 从其他文件使用电子远程

问题描述

我有一个文件,其中包含一个打开文件打开对话框的函数。我想从应用程序的菜单中调用该功能。但是当我使用require文件中的函数时,我得到一个错误。

代码:

主.js:

const { app, BrowserWindow, Menu } = require('electron');
const url = require('url');
const path = require('path');
const { openFile } = require('./index.js');

let win;

function createWindow() {
    win = new BrowserWindow({
        width: 800,
        height: 600,
        icon: __dirname + 'src/styles/media/icon.ico',
        webPreferences: {
            nodeIntegration: true,
            enableRemoteModule: true,
        },
    });
    win.loadURL(
        url.format({
            pathname: path.join(__dirname, 'src/index.html'),
            protocol: 'file:',
            slashes: true,
        })
    );
    var menu = Menu.buildFromTemplate([
        {
            label: 'File',
            submenu: [
                {
                    label: 'Open File',
                    click() {
                        openFile();
                    },
                    accelerator: 'CmdOrCtrl+O',
                }
            ]
        }]);
    Menu.setApplicationMenu(menu);
}

app.on('ready', createWindow);

index.js:

const { dialog } = require('electron').remote;

function openFile() {
    dialog.showOpenDialog({
        title: 'Open File',
        properties: ['openFile'],
    });
}

module.exports = {
    openFile,
};

索引.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <link rel="stylesheet" href="styles/style.css" />
        <title>Stonecutter</title>
    </head>
    <body>
        <script src="./index.js"></script>
    </body>
</html>

错误: 错误

当我做同样的事情但没有required代码时工作正常:

// index.js
// --------
// This code works
function openFile() {
    console.log('Open file');
}

module.exports = {
    openFile,
};

// Main.js is the same

标签: javascriptnode.jselectron

解决方案


您在主进程中使用遥控器。这就是导致问题的原因。远程是您在渲染器进程中使用的(BrowserView 所需的脚本)。所以你需要为 main 和 renderer 进程编写两个不同的 openFile 函数。

因此,当您需要时index.jsmain.js这就是导致错误的原因。您需要确定您在主进程或渲染器中的位置。观看open-file.js下面的内容,了解如何操作。

总而言之,它应该看起来像这样:

main.js

const { app, BrowserWindow, Menu } = require('electron');
const url = require('url');
const path = require('path');
const {openFile} = require('./open-file')

let win;

function createWindow() {
    win = new BrowserWindow({
        width: 800,
        height: 600,
        icon: __dirname + 'src/styles/media/icon.ico',
        webPreferences: {
            nodeIntegration: true,
            enableRemoteModule: true,
        },
    });
    win.loadURL(
        url.format({
            pathname: path.join(__dirname, 'index.html'),
            protocol: 'file:',
            slashes: true,
        })
    );

  }

app.on('ready', () => {
  createWindow()
  var menu = Menu.buildFromTemplate([
  {
      label: 'File',
      submenu: [
          {
              label: 'Open File',
              click() {
                  openFile();
              },
              accelerator: 'CmdOrCtrl+O',
          }
      ]
  }]);
  Menu.setApplicationMenu(menu);
})

index.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <link rel="stylesheet" href="styles/style.css" />
        <title>Stonecutter</title>
    </head>
    <body>
      <button id="open-file">Open file</button>
      <script>
        const {openFile} = require('./open-file.js')

        document.querySelector('#open-file').addEventListener('click', () => openFile())
      </script>
    </body>
</html>

open-file.js

const electron = require('electron');

// electron.remote for Renderer Process and electron for Main Process
const {dialog} = (electron.remote || electron)

function openFile() {
    dialog.showOpenDialog({
        title: 'Open File',
        properties: ['openFile'],
    });
}

module.exports = {
    openFile,
};


此示例按您的预期工作。文件open-file.js就是你在index.js.

这是因为 Electron 在不同的进程中运行它的部分:第一个是Main 进程。这是你在跑步时得到的地方electron main.js。第二个是Renderer 进程在单独的 os 进程中运行。这是您调用的地方win.loadURL(),它的 API 和库集略有不同。


推荐阅读