Auto-Updater
L’auto-updater permette di distribuire aggiornamenti automatici agli utenti senza che debbano scaricare e reinstallare manualmente l’applicazione.
Panoramica
Electron offre due approcci per gli aggiornamenti automatici:
autoUpdaternativo — usa Squirrel (Windows/macOS), richiede un server di aggiornamentoelectron-updater(da electron-builder) — più flessibile, supporta GitHub Releases, S3 e server personalizzati
electron-updater (Consigliato)
La libreria electron-updater è la soluzione più popolare e flessibile.
Installazione
npm install electron-updater
Configurazione Base
// main.js
const { app, BrowserWindow, ipcMain } = require('electron');
const { autoUpdater } = require('electron-updater');
// Configura il logger
autoUpdater.logger = require('electron-log');
autoUpdater.logger.transports.file.level = 'info';
app.whenReady().then(() => {
const mainWindow = createWindow();
// Controlla gli aggiornamenti all'avvio
autoUpdater.checkForUpdatesAndNotify();
});
Gestire gli Eventi
// Un aggiornamento è disponibile
autoUpdater.on('update-available', (info) => {
mainWindow.webContents.send('update:available', {
version: info.version,
releaseNotes: info.releaseNotes,
});
});
// Nessun aggiornamento disponibile
autoUpdater.on('update-not-available', () => {
console.log('App già aggiornata');
});
// Progresso del download
autoUpdater.on('download-progress', (progress) => {
mainWindow.webContents.send('update:progress', {
percent: Math.round(progress.percent),
transferred: progress.transferred,
total: progress.total,
bytesPerSecond: progress.bytesPerSecond,
});
});
// Download completato
autoUpdater.on('update-downloaded', (info) => {
mainWindow.webContents.send('update:downloaded', {
version: info.version,
});
});
// Errore durante l'aggiornamento
autoUpdater.on('error', (error) => {
console.error('Errore aggiornamento:', error.message);
mainWindow.webContents.send('update:error', error.message);
});
Installare l’Aggiornamento
// L'utente conferma l'installazione
ipcMain.on('update:install', () => {
autoUpdater.quitAndInstall();
});
UI nel Renderer
// preload.js
contextBridge.exposeInMainWorld('updater', {
checkForUpdates: () => ipcRenderer.invoke('update:check'),
installUpdate: () => ipcRenderer.send('update:install'),
onUpdateAvailable: (cb) => ipcRenderer.on('update:available', (_e, info) => cb(info)),
onProgress: (cb) => ipcRenderer.on('update:progress', (_e, progress) => cb(progress)),
onDownloaded: (cb) => ipcRenderer.on('update:downloaded', (_e, info) => cb(info)),
onError: (cb) => ipcRenderer.on('update:error', (_e, msg) => cb(msg)),
});
// renderer.js
window.updater.onUpdateAvailable((info) => {
showBanner(`Aggiornamento ${info.version} disponibile. Download in corso...`);
});
window.updater.onProgress((progress) => {
updateProgressBar(progress.percent);
});
window.updater.onDownloaded((info) => {
showDialog({
title: 'Aggiornamento pronto',
message: `La versione ${info.version} è stata scaricata. Riavviare per installare?`,
onConfirm: () => window.updater.installUpdate(),
});
});
Pubblicare su GitHub Releases
Configurazione package.json
{
"build": {
"publish": [
{
"provider": "github",
"owner": "tuo-username",
"repo": "tuo-repo"
}
]
}
}
Pubblicare un Aggiornamento
# Incrementa la versione
npm version patch # o minor, o major
# Build e pubblica
npx electron-builder --publish always
Questo crea una release su GitHub con i file dell’installer. L’auto-updater controllerà automaticamente le nuove release.
Configurazione Avanzata
Controllare gli Aggiornamenti Manualmente
// Non controllare automaticamente all'avvio
autoUpdater.autoDownload = false;
// Controlla manualmente
ipcMain.handle('update:check', async () => {
const result = await autoUpdater.checkForUpdates();
return result?.updateInfo;
});
// Scarica quando l'utente conferma
ipcMain.handle('update:download', () => {
autoUpdater.downloadUpdate();
});
Canale di Aggiornamento
// Usare un canale beta
autoUpdater.channel = 'beta';
// Permettere downgrade
autoUpdater.allowDowngrade = false;
Intervallo di Controllo
// Controlla ogni 4 ore
setInterval(() => {
autoUpdater.checkForUpdatesAndNotify();
}, 4 * 60 * 60 * 1000);
Note Importanti
- Firma del codice: Su macOS e Windows, l’app deve essere firmata per gli aggiornamenti automatici
- Solo app distribuite: L’auto-updater funziona solo con app packaged, non durante lo sviluppo
- Test locale: Usa
autoUpdater.forceDevUpdateConfig = trueper testare in sviluppo - ASAR: L’app deve essere packaged in formato ASAR (default con electron-builder)
Testare l’Auto-Updater
// Solo in sviluppo
if (!app.isPackaged) {
// Simula un controllo aggiornamento
autoUpdater.forceDevUpdateConfig = true;
// Oppure usa un server locale
autoUpdater.setFeedURL({
provider: 'generic',
url: 'http://localhost:8080/updates',
});
}