Можно ли вызвать код Ionic 4 / Capacitor Electron из части приложения Ionic?

Я исследую использование Ionic 4/ Capacitor для целевой Windows с помощью опции Electron, для приложения, в котором я хочу использовать SQLite.

Насколько я вижу, с помощью плагина Ionic Native SQLite, который упаковывает этот плагин Cordova, "из коробки" поддерживается Windows, а не Desktop, который работает с использованием Electron в оболочке Ionic Capacitor.

Мой план состоял в том, чтобы посмотреть, смогу ли я использовать пакет Electron SQLite, а затем вызвать его из моего Ionic-приложения, создав класс-оболочку для Ionic- натива, аналогичный тому, который я использовал для получения поддержки браузера, следуя этому наставлению.

Если я могу вызвать код Electron из моего приложения Ionic, то я не могу понять, почему это не сработает.

Итак, мой вопрос здесь, могу ли я вызвать код (я добавлю функции для использования SQlite), который я добавляю в приложение Electron хостинга из Ионического (веб) кода? И если да, то как?

Заранее благодарю за любую помощь

[Update1]

Попробовал следующее...

Со страницы Ionic у меня есть обработчик нажатия кнопки, где я поднимаю событие..

export class HomePage {

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

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

Затем в рамках проектов "Электрон" index.js, Я старался..

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

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

Но ни один не работал.

Я должен отметить, что я знаю очень мало об Electron. Это мое первое знакомство с ним (через конденсатор)

1 ответ

Если кому-то интересно, вот как я это решил. Я использую 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 (electronic.ts). Вероятно, использование шаблона singleton - лучшая идея.

Надеюсь, это поможет.

Обновить

Вы можете общаться из процесса рендеринга с вашим основным процессом (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();
});

Да, ты можешь! Помните, электрон использует хром, и у вас есть поддержка

Вчера я углубился в это и у вас есть пример использования angular(это должно относиться и к ionic). в вашей службе объявите требование, чтобы мы могли его использовать

  //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 в электронной папке

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

Вероятно, это не правильный способ получить к нему доступ, но это лучший способ, который я мог найти. Насколько я понимаю, ipcRenderer используется, когда у вас есть несколько браузеров, которые общаются друг с другом в электроне. поэтому в нашей ситуации это позволяет нашему веб-слою связываться с электронным материалом

Другие вопросы по тегам