首页 > 解决方案 > ipcMain:event.reply 不是函数

问题描述

我制作了一个简单的Electron应用程序,它使用ipcMainipcRenderer. 这是代码,这是有道理的:

main.js

const { app, BrowserWindow, ipcMain } = require('electron')
const { spawn, exec } = require('child_process')

let win

function createWindow() {
    win = new BrowserWindow({
      width: 800,
      height: 600,
      minWidth: 610,
      minHeight: 470,
      webPreferences: {
        nodeIntegration: true
      }
    })

  win.loadFile('index.html')
  win.webContents.openDevTools()
}

app.on('ready', createWindow)

ipcMain.on("checkPerl", function(e){
    tryToRun("perl", ["-v"])
        .then(function(){ e.reply("checkPerlReply", true) })
        .catch(function(){ e.reply("checkPerlReply", false) })

})

function tryToRun(cmd, args){
  return new Promise(function(resolve, reject){ 
    // some code 
  })
}

渲染器.js

const { ipcRenderer } = require('electron')

class Chdump {

    checkPerl(){
        this.message("Проверяем Perl...")
        let p = new Promise(function(resolve, reject){
            ipcRenderer.send("checkPerl", true)
            ipcRenderer.on("checkPerlReply", function(event, res){
                if (res) resolve()
                else reject()
            })
        })
        return p
    }

    start(){
        let self = this
        this.checkPerl()
        .then(function(){ console.log("Perl is installed") })
        .catch(function(){ console.log("Perl is not installed") })
    }
}

let app = new Chdump()
app.start()

我跳过了一些与问题无关的代码。此代码在我使用 NodeJS 运行时正常运行electron .,但在打包应用程序后出现以下错误:

UnhandledPromiseRejectionWarning: TypeError: e.reply is not a function

此错误引用 main.js 中的以下字符串:

    tryToRun("perl", ["-v"])
        .then(function(){ e.reply("checkPerlReply", true) })
        .catch(function(){ e.reply("checkPerlReply", false) })

我添加console.log(e)了查看事件对象并获得以下内容:

{ preventDefault: [Function: preventDefault],
  sender:
   WebContents {
     webContents: [Circular],
     history:
      [ 'file:///home/kolesnikov/changedump/resources/app/index.html' ],
     currentIndex: 0,
     pendingIndex: -1,
     inPageIndex: -1,
     _events:
      { 'navigation-entry-commited': [Function],
        'ipc-message': [Function],
        'ipc-message-sync': [Function],
        'pepper-context-menu': [Function],
        '-did-get-response-details': [Function],
        '-did-get-redirect-request': [Function],
        'devtools-reload-page': [Function],
        '-new-window': [Function],
        '-web-contents-created': [Function],
        '-add-new-contents': [Function],
        'will-navigate': [Function],
        'did-navigate': [Function],
        destroyed: [Function],
        'devtools-opened': [Function],
        move: [Function],
        activate: [Function],
        'page-title-updated': [Function] },
     _eventsCount: 17,
     _maxListeners: 0,
     browserWindowOptions:
      { width: 800,
        height: 600,
        minWidth: 610,
        minHeight: 470,
        webPreferences: [Object] } } }

我尝试对使用 NodeJS 运行的非打包应用程序做同样的事情,结果却出人意料地不同:

{ preventDefault: [Function: preventDefault],
  // [...] looks the same as a previous object
  frameId: 1,
  reply: [Function] }

第二个Event对象看起来不错,它有一个reply属性。我还是不明白,为什么Event对象打包后electron没有属性。reply

你有什么想法?

标签: node.jselectron

解决方案


使用 e.sender.send 代替 e.reply

ipcMain.on("checkPerl", function(e){
    tryToRun("perl", ["-v"])
        .then(function(){ e.sender.send("checkPerlReply", true) })
        .catch(function(){ e.sender.send("checkPerlReply", false) })

})

推荐阅读