Skip to main content

Electron


title: Documentazione Electron Integration sidebar_position: 2

⚡ Integrazione Electron + Angular

Questo progetto è una desktop app costruita con Electron e Angular.
Electron gestisce la finestra nativa, la comunicazione con il sistema operativo e le stampanti. Angular fornisce l’interfaccia grafica e i flussi applicativi.

La comunicazione tra i due livelli avviene tramite IPC (Inter Process Communication) e un preload script sicuro che espone API custom a window.


🖥️ main.js

Il file main.js è l’entry point di Electron.
Principali responsabilità:

  • Creazione finestra principale (BrowserWindow):

    const win = new BrowserWindow({
    width: 1024,
    height: 850,
    webPreferences: {
    preload: path.join(app.getAppPath(), 'preload.js'),
    nodeIntegration: true,
    }
    });
    win.loadFile('dist/dispenser-barcode-electron-app/browser/index.html');
  • Gestione scorciatoie globali:

    globalShortcut.register("CommandOrControl+Shift+I", () => {
    if (mainWindow) {
    mainWindow.openDevTools();
    }
    });
  • Gestione IPC per la stampa:

    Riceve eventi dal renderer (print-action) e apre una connessione TCP/IP verso la stampante.

    ipcMain.on('print-action', (event, arg) => {
    const client = new net.Socket();
    client.connect(arg.printerPort, arg.printerIp, () => {
    client.write(arg.message);
    });
    client.on('data', (data) => console.log('Risposta:', data.toString()));
    client.on('error', (err) => console.error('Errore:', err));
    });
  • Mostrare popup nativi (dialog.showMessageBox):

    function showPopupMessage(popup, event) {
    dialog.showMessageBox({
    type: 'info',
    buttons: popup.buttons.map(elm => elm.name),
    title: popup.popupTitle,
    message: popup.messageTitle,
    detail: popup.message
    }).then((result) => {
    if (popup?.buttons?.[result.response]?.onClickTrigger) {
    event.reply(
    popup.buttons[result.response].onClickTrigger.ipcChannel,
    popup.buttons[result.response].onClickTrigger.args
    );
    }
    });
    }
  • Gestione menu applicazione:

    Definisce voci come File > Quit o File > Aggiungi Stampante, che inviano eventi al frontend.

    const menu = new Menu();
    menu.append(new MenuItem({
    label: 'file',
    submenu: [
    { role: 'quit' },
    {
    label: 'Aggiungi Stampante',
    click: () => {
    mainWindow.webContents.send('add-printer', 'Aggiungi una nuova stampante');
    }
    }
    ]
    }));
    Menu.setApplicationMenu(menu);

🔌 preload.js

Il file preload.js espone in maniera sicura delle API al contesto window di Angular. Utilizza contextBridge e ipcRenderer.

const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('electronAPI', {
addPrinter: (callback) =>
ipcRenderer.on('add-printer', (_event, value) => callback(value)),

printAction: (value) =>
ipcRenderer.send('print-action', value),
});

Funzionalità esposte

  • addPrinter(callback) → notifica Angular quando viene aggiunta una stampante.

  • printAction({ printerIp, printerPort, message }) → invia una richiesta di stampa al main process.

📝 typings.d.ts

Per permettere ad Angular/TypeScript di conoscere le nuove API aggiunte a window, si dichiara un’interfaccia globale:

// src/typings.d.ts
interface Window {
electronAPI: {
addPrinter: (value: any) => void;
printAction: (value: {
printerIp: string,
printerPort: number,
message: string
}) => void
};
}

In questo modo, Angular può invocare:

window.electronAPI.printAction({
printerIp: "192.168.0.100",
printerPort: 9100,
message: "TEST PRINT"
});

🔄 Flusso di comunicazione

  • Angular (frontend) invoca window.electronAPI.printAction(...).

  • Preload.js inoltra la richiesta via ipcRendereripcMain.

  • Main.js riceve l’evento e apre connessione TCP verso la stampante, inviando il messaggio.

  • La stampante risponde → main.js logga o invia eventuale feedback.

  • Eventuali popup o messaggi vengono mostrati tramite dialog o inviati al renderer con webContents.send.

✅ Vantaggi della struttura

  • Sicurezza: l’uso di contextBridge limita l’accesso diretto ad ipcRenderer.

  • Separazione responsabilità:

    • Angular gestisce solo la UI e logica di business.

    • Electron (main.js) gestisce interazioni native (stampanti, finestre, menu).

  • Estendibilità: aggiungere nuove funzioni (es. gestione file system) richiede solo:

    • Nuovo handler in main.js.

    • Metodo esposto in preload.js.

    • Aggiornamento typings.d.ts.