Vue/Electron主进程和渲染进程之间的IPC通信

3
我正在尝试在Vue浏览器应用程序和Electron主进程之间建立通信,但它没有起作用。在调用startBot()之前,我就收到一个错误消息,说__Dirname未知。但是这个常量在代码中找不到。我做错了什么?这是我打开带有预加载的浏览器窗口的background.js文件。这样做的目的是使窗口可用于浏览器进程。请参考链接:https://gist.github.com/Quenos/7d6dbe4f5410739499ea9e3b0b4f961a.js
function createWindow() {
  // Create the browser window.
  win = new BrowserWindow({
    width: 1300,
    height: 1100,
    title: "Hedgehog TRDR Bot",
    icon: path.join(__static, "hedgehog.jpg"),
    webPreferences: {
      nodeIntegration: false,
      contextIsolation: true,
      enableRemoteModule: false,
      // __static is set by webpack and will point to the public directory
      preload: path.resolve(__static, "preload.js"),
    },
  });

这是preload.js

const { contextBridge, ipcRenderer } = require("electron");

const validChannels = ["READ_FILE", "WRITE_FILE"];
contextBridge.exposeInMainWorld("ipc", {
  send: (channel, data) => {
    if (validChannels.includes(channel)) {
      ipcRenderer.send(channel, data);
    }
  },
  on: (channel, func) => {
    if (validChannels.includes(channel)) {
      // Strip event as it includes `sender` and is a security risk
      ipcRenderer.on(channel, (event, ...args) => func(...args));
    }
  },
});

主进程包含侦听器,然后进行文件处理。
const { ipcMain } = require("electron");
const fs = require("fs");
var file;

ipcMain.on("OPEN_FILE", (event, payload) => {
  console.log("daaro");
  file = fs.createWriteStream(payload.path);
  event.reply("OPEN_FILE", { content: "roger" });
});

ipcMain.on("TEST_FILE", (event, payload) => {
  console.log("daaro");
  file.write(payload.path);
  event.reply("OPEN_FILE", { content: "roger" });
});

还有发送文件处理请求的浏览器进程:

async startBot() {
  window.ipc.send("OPEN_FILE", { path: "./HH_trdr_bot.csv" });
}
3个回答

3

2
你最终解决了这个问题吗? 当我在.vue文件中使用它时,我收到“TypeError:window.ipc.on不是函数”的错误。 - user3067684
1
我也遇到了这个错误,TypeError: window.ipc.on is not a function,你是怎么解决的?@MPL,@user3067684 - Saqib Shehzad

1

Vue CLI插件Electron Builder的文档包含如何操作的描述,但有点分散。

首先,请参阅如何配置预加载脚本

vue.config.js

module.exports = {
  // ...
  pluginOptions: {
    electronBuilder: {
      preload: 'src/preload.js',
    }
  }
}

然后,在BrowserWindowwebPreferences.preload构造选项中重复路径。

preload: path.join(__dirname, 'preload.js')

最后,在src/preload.js中按照无需 Node Integration 的 IPC的描述将 IPC Renderer 暴露出来。
import { contextBridge, ipcRenderer } from 'electron'

// Expose protected methods that allow the renderer process to use
// the ipcRenderer without exposing the entire object
contextBridge.exposeInMainWorld('ipcRenderer', {
  send: (channel, data) => {
    // whitelist channels
    let validChannels = ['toMain']
    if (validChannels.includes(channel)) {
      ipcRenderer.send(channel, data)
    }
  },
  receive: (channel, func) => {
    let validChannels = ['fromMain']
    if (validChannels.includes(channel)) {
      // Deliberately strip event as it includes `sender`
      ipcRenderer.on(channel, (event, ...args) => func(...args))
    }
  }
})

当订阅事件的组件即将被销毁时,取消订阅事件监听器也是一个好主意。


0

我通过将preload.js文件放置在公共文件夹中,使我的工作正常运行,在https://nklayman.github.io/vue-cli-plugin-electron-builder/guide/guide.html#preload-files文档中,在Folder Structure部分下有一个小图表,上面写着├── public/ # Files placed here will be available through __static or process.env.BASE_URL,所以我所做的就是简单地按照文档中描述的使用__static变量,并将其附加到\preload.js

  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: false,
      contextIsolation: true,
      enableRemoteModule: false,
      preload: __static + '/preload.js', // <-- simple solution
    }
  })

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接