0

我目前在接收从我的主进程到我的渲染器进程(在 Angular 中)的活动窗口的恒定流时遇到一些问题。我知道接收每秒更新会破坏我的应用程序,所以我试图使用 setTimeout 来限制它。但这仍然行不通。我怎样才能解决这个问题?

渲染器 - Angular 中的组件

  ipc: IpcRenderer | undefined | null;

  constructor(private electronService: ElectronService) { }

  ngAfterViewInit(): void {
    this.getActiveWindow();
  }

  getActiveWindow() {
    while(this.electronService.isElectronApp) {
      this.ipc = this.electronService.ipcRenderer;
      this.ipc.send('get-active-window');
      this.ipc.on('get-active-window-reply', (_event, reply) => {
        console.log(reply);
      });
    }
  }

main.js

const activeWindows = require('electron-active-window');

ipcMain.on('get-active-window', (_event, _arg) => {
  let i = 0;
  setTimeout(function () {
    activeWindows().getActiveWindow().then((result) => {
      win.webContents.send("get-active-window-reply", result)
    })
  }, 10000 * i)
});

到目前为止,我已经尝试了以下方法,但这只会显示一次活动窗口。我想跟踪所有的变化:

渲染器 - Angular 中的组件

 ngOnInit(): void {
    this.getActiveWindow();
  }

  getActiveWindow() {
    if(this.electronService.isElectronApp) {
      this.ipc = this.electronService.ipcRenderer;
      this.ipc.send('get-active-window');
      this.ipc.on('get-active-window-reply', (_event, reply) => {
        console.log(reply);
      });
    }
  }

main.js

ipcMain.on('get-active-window', (_event, _arg) => {
  activeWindows().getActiveWindow().then((result) => {
    win.webContents.send("get-active-window-reply", result)
  });
});
4

1 回答 1

2

您只收到一次活动窗口,因为您只在ngOnInit.

所以在我看来,你目前有两种选择。

  1. 您每隔几秒钟就向客户端请求一次信息
  2. 您让 Electron 应用程序通知客户端有关窗口的信息

选项1:(仅解决方案afaik)

渲染组件

import { interval } from 'rxjs';

...

getActiveWindow() {
  if(this.electronService.isElectronApp) {
    this.ipc = this.electronService.ipcRenderer;
    
    this.ipc.on('get-active-window-reply', (_event, reply) => {
      console.log(reply);
    });

    // A request directly to get "instant" feedback
    this.ipc.send('get-active-window');

    // You could also use setInterval but I prefer rxjs more ;)
    // Don't forget to unsubscribe in ngOnDestroy
    interval(2000).subscribe(() => {
      this.ipc.send('get-active-window');
    });
  }
}

此解决方案会产生大量开销,因为您不需要每隔几秒更新一次活动窗口,因此我推荐此解决方案

选项2(建议不工作):

main.js

// Sends a message every time a BrowserWindow is created
app.on('browser-window-created', (event, window) => {
  this.sendActiveWindows();
});

// Respond to the client request
ipcMain.on('get-active-window', (_event, _arg) => {
   this.sendActiveWindows();
});

// Helper function
sendActiveWindows(){
  activeWindows().getActiveWindow().then((result) => {
    win.webContents.send("get-active-window-reply", result)
  });
}

如果您还需要关闭窗口时的信息,您需要添加一个监听器BrowserWindow.on('closed',...)(更多here)并通知您的客户。

render.component.ts(仅添加评论)

getActiveWindow() {
  if(this.electronService.isElectronApp) {
    this.ipc = this.electronService.ipcRenderer;
    // Request the currently active windows, 
    // otherwise this info is missing until new window is created
    this.ipc.send('get-active-window');
    this.ipc.on('get-active-window-reply', (_event, reply) => {
      console.log(reply);
    });
  }
}

此解决方案更合适,因为您的客户仅在窗口数量发生变化时才会收到通知,所以我推荐这个

更新

在聊天中澄清问题后,您不能使用选项 2,因为您想检测操作系统的活动窗口而不是 Electron 应用程序的活动窗口。由于 info选项 1是这里唯一有效的解决方案

于 2021-12-10T14:38:13.160 回答