我可以从应用程序的Ionic部分调用Ionic 4 / Capacitor Electron代码吗?

zsohkypk  于 2023-10-14  发布在  Electron
关注(0)|答案(2)|浏览(132)

我正在研究通过Electron选项使用Ionic 4/ Capacitor来针对Windows,用于我想要使用SQLite的应用程序。
使用Ionic Native SQLite插件,它 Package 了this Cordova plugin,开箱即用,据我所知,Windows支持的是UWP,而不是桌面,它在离子电容器 Package 器中使用Electron运行。
我的计划是看看我是否可以使用Electron SQLite包,然后从我的Ionic应用程序调用它,方法是为Ionic本机创建一个 Package 器类,类似于我过去通过遵循this tutorial来获得浏览器支持的方法
如果我可以从我的Ionic应用程序调用Electron代码,那么我不明白为什么这不起作用。
所以,我的问题是,我可以从Ionic(Web)代码中调用代码(我将添加函数以使用SQLite)添加到托管Electron应用程序吗?如果是的话,是怎么做到的?

更新1

已尝试以下操作...
从一个离子页面,我有一个按钮点击处理程序,我提出了一个事件。

export class HomePage {

 public devtools() : void {
  let emit = new EventEmitter(true);
  emit.emit('myEvent');

   var evt = new CustomEvent('myEvent');
   window.dispatchEvent(evt);
  }

然后在Electron项目index.js中,我尝试了。

mainWindow.webContents.on('myEvent', () => {
      mainWindow.openDevTools();
    });

    const ipc = require('electron').ipcMain
    ipc.on('myEvent', (ev, arg) => {
      mainWindow.openDevTools();
    });

但都没有用。
我对电子知之甚少。这是我第一次接触它(通过电容器)。

wz1wpwve

wz1wpwve1#

如果有人感兴趣,这就是我解决这个问题的方法。我正在使用Ionic 4 / Capacitor + Vue 3。
在我的入口文件(app.ts)中,我声明了一个名为Window的全局接口,如下所示:

// app.ts
declare global { interface Window { require: any; } }

然后,我写了下面的类:

// electron.ts
import { isPlatform } from '@ionic/core';

export class Electron
{
    public static isElectron = isPlatform(window, 'electron');
    public static getElectron()
    {
        if (this.isElectron)
        {
            return window.require('electron');
        }
        else
        {
            return null;
        }
    }
    public static getIpcRenderer()
    {
        if (this.isElectron)
        {
            return window.require('electron').ipcRenderer;
        }
        else
        {
            return null;
        }
    }
    public static getOs()
    {
        if (this.isElectron)
        {
            return window.require('os');
        }
        else
        {
            return null;
        }
    }
}

我是这样用的:

//electronabout.ts
import { IAbout } from './iabout';
import { Plugins } from '@capacitor/core';
import { Electron } from '../utils/electron';

export class ElectronAbout implements IAbout
{
  constructor() { }
  public async getDeviceInfo()
  {
    let os = Electron.getOs();
    let devInfo =
    {
      arch: os.arch(),
      platform: os.platform(),
      type: os.type(),
      userInfo: os.userInfo()
    };

    return devInfo;
  }
  public async showDeviceInfo()
  {
    const devInfo = await this.getDeviceInfo();
    await Plugins.Modals.alert({ title: 'Info from Electron', message: JSON.stringify(devInfo) });
  }
}

这是工作,但当然,我仍然需要重构电子类(electron.ts)。也许使用单例模式是一个更好的主意。
我希望这能帮上忙。

更新

你可以从渲染进程与你的主进程(index.js)进行通信,如下所示:

//somefile.ts
if (Electron.isElectron)
{
     let ipc = Electron.getIpcRenderer();
     ipc.once('hide-menu-button', (event) => { this.isMenuButtonVisible = false; });
 }

//index.js
let newWindow = new BrowserWindow(windowOptions);
newWindow.loadURL(`file://${__dirname}/app/index.html`);
newWindow.webContents.on('dom-ready', () => {
         newWindow.webContents.send('hide-menu-button');
         newWindow.show();
});
ds97pgxw

ds97pgxw2#

我昨天深入研究了这个问题,并为你提供了一个使用angular的例子(这也适用于ionic)。在您服务中声明require,以便我们可以使用它

//Below your imports
  declare function require(name:string);

然后在任何你想使用它的函数中:

// Require the ipcRenderer so we can emit to the ipc to call a function
// Use ts-ignore or else angular wont compile
// @ts-ignore
const ipc = window.require('electron').ipcRenderer;
// Send a message to the ipc
// @ts-ignore
ipc.send('test', 'google');

然后在创建的index.js中的electron文件夹中

// Listening for the emitted event
ipc.addListener('test', (ev, arg) => {
    // console.log('ev', ev);
    console.log('arg', arg);
});

这可能不是正确的方式来访问它,但它的最好的方式,我可以找到。根据我的理解,ipcRenderer是用于当你有多个浏览器在electron中相互交谈时。所以在我们的情况下,它使我们的网络层能够与电子设备进行通信,

相关问题