Auto-Updater: Doppelstart verhindern + Download-Status sichtbar

- State-Tracking im Main-Prozess (idle/checking/downloading/ready)
- Manueller Check gibt aktuellen Status zurück statt Squirrel-Doppelstart
- Auto-Check nur wenn idle (kein Konflikt mit laufendem Download)
- Frontend synchronisiert Status beim Mount und Modal-Öffnen
- getUpdateStatus IPC für synchrone Status-Abfrage

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Daniel 2026-03-08 16:27:29 +01:00
parent 2c6ac0745d
commit d909909591
3 changed files with 61 additions and 13 deletions

View file

@ -33,43 +33,75 @@ function setupAutoUpdater() {
return;
}
// State-Tracking: verhindert Doppelstarts und bewahrt Status
let updateState = 'idle'; // idle | checking | downloading | ready
autoUpdater.on('checking-for-update', () => {
console.log('[AutoUpdater] Checking for updates...');
updateState = 'checking';
});
autoUpdater.on('update-available', () => {
console.log('[AutoUpdater] Update available, downloading...');
updateState = 'downloading';
if (mainWindow) mainWindow.webContents.send('update-available');
});
autoUpdater.on('update-downloaded', (_event, releaseNotes, releaseName) => {
console.log('[AutoUpdater] Update downloaded:', releaseName || 'new version');
updateState = 'ready';
if (mainWindow) mainWindow.webContents.send('update-ready');
});
autoUpdater.on('update-not-available', () => {
console.log('[AutoUpdater] App is up to date.');
updateState = 'idle';
if (mainWindow) mainWindow.webContents.send('update-not-available');
});
autoUpdater.on('error', (err) => {
console.error('[AutoUpdater] Error:', err.message);
updateState = 'idle';
if (mainWindow) mainWindow.webContents.send('update-error', err.message);
});
// Handle install-update request from renderer
ipcMain.on('install-update', () => {
autoUpdater.quitAndInstall();
});
autoUpdater.on('update-not-available', () => {
console.log('[AutoUpdater] App is up to date.');
if (mainWindow) mainWindow.webContents.send('update-not-available');
});
// Manual check from renderer
// Manual check from renderer — gibt aktuellen Status zurück statt Doppelstart
ipcMain.on('check-for-updates', () => {
if (updateState === 'downloading') {
if (mainWindow) mainWindow.webContents.send('update-available');
return;
}
if (updateState === 'ready') {
if (mainWindow) mainWindow.webContents.send('update-ready');
return;
}
if (updateState === 'checking') {
return; // bereits am Prüfen
}
try { autoUpdater.checkForUpdates(); } catch (e) { console.error('[AutoUpdater]', e.message); }
});
autoUpdater.on('error', (err) => {
console.error('[AutoUpdater] Error:', err.message);
if (mainWindow) mainWindow.webContents.send('update-error', err.message);
// Sync-Abfrage: Frontend kann aktuellen Status beim Modal-Öffnen abfragen
ipcMain.on('get-update-status', (event) => {
event.returnValue = updateState;
});
// Check for updates after 5 seconds, then every 30 minutes
// Auto-Check nach 5 Sek, dann alle 30 Min (nur wenn idle)
setTimeout(() => {
try { autoUpdater.checkForUpdates(); } catch (e) { console.error('[AutoUpdater]', e.message); }
if (updateState === 'idle') {
try { autoUpdater.checkForUpdates(); } catch (e) { console.error('[AutoUpdater]', e.message); }
}
}, 5000);
setInterval(() => {
try { autoUpdater.checkForUpdates(); } catch (e) { console.error('[AutoUpdater]', e.message); }
if (updateState === 'idle') {
try { autoUpdater.checkForUpdates(); } catch (e) { console.error('[AutoUpdater]', e.message); }
}
}, 30 * 60 * 1000);
}

View file

@ -9,6 +9,7 @@ contextBridge.exposeInMainWorld('electronAPI', {
onUpdateNotAvailable: (callback) => ipcRenderer.on('update-not-available', callback),
onUpdateError: (callback) => ipcRenderer.on('update-error', (_e, msg) => callback(msg)),
checkForUpdates: () => ipcRenderer.send('check-for-updates'),
getUpdateStatus: () => ipcRenderer.sendSync('get-update-status'),
installUpdate: () => ipcRenderer.send('install-update'),
setStreaming: (active) => ipcRenderer.send('streaming-status', active),
showNotification: (title, body) => ipcRenderer.send('show-notification', title, body),