首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >未定义的角11电子IPC通信“发送”

未定义的角11电子IPC通信“发送”
EN

Stack Overflow用户
提问于 2021-03-15 11:16:47
回答 1查看 802关注 0票数 1

我做了我的第一次尝试,并希望使用电子apis的角度渲染过程。我按照指示进

指令创建角-Electron应用程序

因此,在我的main.js文件中,我添加了:

代码语言:javascript
复制
const {app, BrowserWindow, ipcMain} = require('electron')

我还补充说

代码语言:javascript
复制
function openModal(){
  const { BrowserWindow } = require('electron');
  let modal = new BrowserWindow({ parent: mainWindow, modal: true, show: false })
  modal.loadURL('https://www.sitepoint.com')
  modal.once('ready-to-show', () => {
    modal.show()
  })
}

ipcMain.on('openModal', (event, arg) => {
  openModal()
})

在我的app.component.ts文件中添加了导入import { IpcRenderer } from 'electron';

我添加了以下构造函数

代码语言:javascript
复制
  private ipc: IpcRenderer
  constructor(){
    if ((<any>window).require) {
      try {
        this.ipc = (<any>window).require('electron').ipcRenderer;
      } catch (e) {
        throw e;
      }
    } else {
      console.warn('App not running inside Electron!');
    }
  }

由于我的CLI不完全清楚icp是否属于IpcRenderer类型,所以我在这一行中添加了

代码语言:javascript
复制
private ipc: IpcRenderer | any;

有此功能

代码语言:javascript
复制
  openModal(){
    console.log("Open a modal");
    this.ipc.send("openModal");
  }

它应该能够向“主”进程发送某种东西。但是如果我调用这个函数,就会得到错误

TypeError:无法读取未定义的属性“发送”

我做错什么了?

EN

回答 1

Stack Overflow用户

发布于 2022-01-28 11:57:17

我也面临着同样的问题,但发现了一个长期的黑客攻击。

致因

看一看这一行:

代码语言:javascript
复制
(<any>window).require

这一行搜索全局窗口对象中的require()方法,该对象是一个NodeJS函数,因此如果使用电子版本> 5,则不会在运行时注入该方法,因为默认情况下,BrowserWindow类的webPreferences -> nodeIntegration属性设置为false。

解决方案

有两种解决办法:

  1. set contextIsolation: false的应用程序将如预期的那样工作,但此次黑客攻击存在安全问题。如这个答案中所引用的

电子应用是伟大的,因为我们可以使用节点,但这种力量是一把双刃剑。如果我们不小心,我们会通过我们的应用程序给某人访问节点的权限,而使用节点,一个坏的参与者可能会破坏您的计算机或删除您的操作系统文件(我想,其中包括其他事情)。

  1. 使用contextBridge 和preload.js:这是从上面的答案和对这个问题的其他答案中派生出来的。

我将提出一个使用角度的解决办法。

webPreferences中,在main.js中创建mainWindow时,进行以下修改:

代码语言:javascript
复制
webPreferences: {
      nodeIntegration: false,
      contextIsolation: true,
      enableRemoteModule: false,
      preload: path.join(__dirname, "preload.js")
    }

main.js所在的同一个目录中,创建一个preload.js文件并在那里添加以下代码(对于这个用例,您可以省略receive()声明,因为它不是必需的)。

代码语言:javascript
复制
const {
    contextBridge,
    ipcRenderer
} = require("electron");

// Expose protected methods that allow the renderer process to use
// the ipcRenderer without exposing the entire object
contextBridge.exposeInMainWorld(
    "api", {
        send: (channel, data) => {
            // whitelist channels
            let validChannels = ["openModal"];
            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));
            }
        }
    }
);

PS:添加这段代码的原因已经在引用的答案中提到了,所以我不会在这里重复。

现在,在运行时,电子将将window.api.send()window.api.receive()方法注入全局window对象中。如果您试图直接访问角组件中的它们,linter将给出错误,因为它们不是在标准窗口对象上定义的。为了解决这个问题,我们将创建一个角服务并注入到我们的应用程序中。此服务将引用在运行时创建的浏览器的窗口对象,并添加上述两个函数。

创建一个WindowRefService并添加以下代码:

window-ref-service.ts

代码语言:javascript
复制
import { Injectable } from '@angular/core';

@Injectable({
  providedIn: 'root'
})

export class WindowRefService {

  getWindow(): any {
    return window;
  }
  constructor() { }
  get nativeWindow(): Window{
    return this.getWindow();
  }
}

不要忘记在AppModule中注册服务:

代码语言:javascript
复制
...

import { WindowRefService } from './window-ref.service';
...
@NgModule{
...
providers: [WindowRefService]
}

之后,将其注入组件中:

代码语言:javascript
复制
 import { WindowRefService } from './window-ref.service';
 ...
 
 private _window:any;
 constructor(windowRef: WindowRefService){
     this._window = windowRef.nativeWindow;
 }
 ...
 //openModal function
 openModal(){
  console.log("Open a modal");
  this._window.api.send("openModal", /* data to be sent, if any*/);
 }

删除构造函数中的private ipc: IpcRenderer | any;和其他现有代码,因为它不是必需的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66636943

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档