https://myservrurl.com/2.0.1/myapp.exe следующую версию приложения. Текущая, на которой тестирую автообновление - 2.0.0.
Долго читал доку и понял, что вот такой вариант должен вполне работать. Но собираю приложение, устанавливаю, запускаю приложение и... ничего не происходит. Если запустить просто ng build && electron . , то в консоли спустя 30 секунд (интервал, по которому запускается autoUpdater.checkForUpdates()) пишет There was a problem updating the application
Error: Can not find Squirrel at AutoUpdater.checkForUpdates
В чём проблема и куда копать?
const {app, BrowserWindow, autoUpdater, dialog} = require('electron');
const log = require('electron-log'); // Подключение модуля логирования
const server = 'https://myservrurl.com/';
const url = `${server}/2.0.1/`;
autoUpdater.setFeedURL({ url });
// интервал для регулярной проверки обновлений
setInterval(() => {
autoUpdater.checkForUpdates();
}, 30 * 1000); // Проверка каждые 30 секунд
autoUpdater.on('update-downloaded', (event, releaseNotes, releaseName) => {
const dialogOpts = {
type: 'info',
buttons: ['Restart', 'Later'],
title: 'Application Update',
message: process.platform === 'win32' ? releaseNotes : releaseName,
detail:
'A new version has been downloaded. Restart the application to apply the updates.'
};
dialog.showMessageBox(dialogOpts).then((returnValue) => {
if (returnValue.response === 0) autoUpdater.quitAndInstall()
})
});
autoUpdater.on('error', (message) => {
console.error('There was a problem updating the application')
console.error(message)
});
// каталог для логов, где будут храниться журналы приложения
log.transports.file.file = 'logfile.log';
log.transports.file.format = '{h}:{i}:{s} {text}'; // формат логов
let appWindow;
app.commandLine.appendSwitch('disable-http-cache');
function createWindow() {
// log.info('Creating appWindow...');
appWindow = new BrowserWindow({
width: 1600,
height: 800,
// alwaysOnTop: true, // должно ли окно всегда оставаться поверх других окон.
frame: false, // Убирает стандартный фрейм с кнопками управления окном
});
// log.info('Loading dist/index.html...');
appWindow.loadFile('dist/index.html');
appWindow.on('closed', function () {
appWindow = null;
});
// Открываем окно в полноэкранном режиме
appWindow.setFullScreen(true);
// проверка, что приложение не запустилось и в открывшемся окне просто белый экран
if (appWindow) {
let reloaded = false;
appWindow.webContents.on('did-finish-load', () => {
if (reloaded) {
return;
}
appWindow.webContents.executeJavaScript(`
document.body.innerText.trim().length > 0
`).then(bodyLoaded => {
// если вдруг что-то пошло не так и программа в итоге
// не запустилась - то она перезапускется принудительно
if (!bodyLoaded) {
reloaded = true;
appWindow.loadFile('dist/index.html');
}
});
});
}
}
// Проверка на наличие другого экземпляра приложения
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) {
// Если другой экземпляр приложения уже активен, то можно отобразить сообщение об ошибке
// dialog.showErrorBox('Ошибка', 'Приложение уже запущено.');
app.quit();
} else {
// Если текущий экземпляр является первым, создаётся окно приложения
app.on('second-instance', (event, commandLine, workingDirectory) => {
if (appWindow) {
// log.info('appWindow show');
appWindow.show();
}
});
app.whenReady().then(() => {
// log.info('createWindow');
createWindow();
});
}
https://github.com/electron/electron/issues/4535
То есть, как я понял, нужно отказаться от nsis в пользу Sqirrel? У меня есть файл electron-builder.json, в котором используется nsis, но, честно говоря, пока не до конца ясно как изменить на Sqirrel и что конкретно для этого нужно cделать? { "appId": "com.example.app", "productName": "myapp", "directories": { "output": "./inst" }, "win": { "target": "nsis", "icon": "icon.ico", "publisherName": "CN=\"MyApp, Inc.\", O=\"MyApp, Inc.\"" }, "nsis": { "oneClick": false, "perMachine": true, "allowToChangeInstallationDirectory": true } }
Удалось настроить автообновление. В целом всё работает, новые версии устанавливаются, если разместить нужные файлы версии по пути https://myserverurl.ru/eleases/ , но если разместить в release более старую версию, чем уже установлена, то в логах пишется "warn: CheckForUpdateImpl: hwhat, local version is greater than remote version", не смотря на то, что у меня проставлено autoUpdater.allowDowngrade = true; Нужно ли что-то ещё, чтобы разрешать установку более старых версий? В документации явно описано, что это должно разрешать установку более старых версий: /** * Whether to allow version downgrade (when a user from the beta channel wants to go back to the stable channel). * * Taken in account only if channel differs (pre-release version component in terms of semantic versioning). * * @default false */ allowDowngrade: boolean; Вот код обновления в app.js: // Определение глобальных переменных для URL и интервала let updateURL = null; let updateInterval = null; let isDownloading = false; // Функция для установки URL и интервала для проверки обновлений function setUpdateURL() { // разрешаем установку более старых версий autoUpdater.allowDowngrade = true; // Устанавливаем URL для проверки обновлений const server = 'https://myserverurl.ru/'; updateURL = `${server}releases/`; // Устанавливаем интервал для регулярной проверки обновлений updateInterval = setInterval(() => { if (!isDownloading) { // Просто проверяем наличие обновлений, без дополнительных проверок autoUpdater.checkForUpdates(); } }, 30 * 1000); // Проверка каждые 30 секунд // Устанавливаем URL для autoUpdater autoUpdater.setFeedURL({ url: updateURL }); } // Обработка начала загрузки autoUpdater.on('update-downloading', () => { isDownloading = true; }); // Обработка завершения загрузки autoUpdater.on('update-downloaded', () => { isDownloading = false; });
Обсуждают сегодня