Electron generic update servisi

Electron builder ile build edilen uygulamalarınız için kendi sunucunuz üzerinden auto update işlemlerini kısaca özetlemeye çalışacağım, eğer electron build yerine başka bir paketleyici kullanıyorsanız burdaki işlemler sizin için çözümleyici olmayacaktır.

electron updater electron builder için olsada ayrı bir bağımlılıktır bu yüzden işlemlere başlamadan önce projenize eklemeniz gerekir

npm install electron-updater --save

electronBuilder confiğiniz içerisinde alttaki kodları eklemelisiniz, bu işlem build sonrasında yml dosyalarınızın oluşmasını sağlayacak

publish: [
    {
        provider: "generic",
        url: 'websiteniz.tld/updates/'
    }
]

özetle builderOptions ayarlarınız aşşağıdaki örneğe benzer bir halde olacak.


{
  "build": {
    "appId": "com.example.yourapp",
    "mac": {
      "target": "dmg"
    },
    "win": {
      "target": "nsis"
    },
    "linux": {
      "target": "snap"
    },
    "publish": [
      {
        "provider": "generic",
        "url": "websiteniz.tld/updates/"
      }
    ]
  }
}

bu işlemlerden sonra build aldığınızda işletim sisteminize göre dist klasörünüzde lates.yml, lates-mac.yml veya lates-linux.yml adında dosyanızda mevcut olacaktır.

windows için exe yeterli gelirken mac için güncelleme işlemi dmg desteklemiyor, eğer dmg kullanıyorsanız mac için build sonrası zip uzantısınında oluşması için target değerini alttaki gibi düzenleyerek dmg ve zip olarak son hallerini alabilirsiniz.

target:[
    {
        "target": "dmg",
        "arch": [
            "universal"
        ]
    },
    {
        "target": "zip",
        "arch": [
            "universal"
        ]
    }
],

tüm bu işlemlerden sonra build yaptığınızda dist klasörünüz içerisinde ihtiyacımız olan dosyalar işletim sistemlerine göre alttaki gibi olacak

windows:

  • appName.exe
  • appName.exe.blockmap
  • lates.yml

mac

  • appName.dmg
  • appName.dmg.blockmap
  • appName.zip
  • appName.zip.blockmap
  • lates-mac.yml

Linux

  • appName.appImage
  • appName.appımage.blockmap
  • lates-linux.yml

Yukarda belirttiğim dosyaları sunucuzda root dizininde updates klasörüne upload edin, builderOptions kısmında publish.url belirttiğiniz klasör hangisi ise oda olabilir, anlattığım örnek de şu şekilde

curl -I https://websiteniz.tld/updates/lates.yml

şeklinde baktığınızda upload ettiğiniz dosya veya dosyalara ait bilgileri alttaki gibi görebiliyor olmalısınız

HTTP/2 200
cache-control: public
date: Tue, 03 Sep 2024 15:37:34 GMT
content-disposition: attachment; filename="appName.exe"
accept-ranges: bytes
content-length: 160272216
vary: User-Agent
content-type: application/x-dosexec
server: Apache/2

burada dikkat etmeniz gereken bir kaç nokta var, eğer yml dosyalarını upload etmek yerine kendiniz oluşturuyor ve dosyaları bir çeşit script ile download ettiriyorsanız accept-ranges ve content-length değerlerinin varlığından kesinlikle emin olun. Bu işlem güncelleme sırasında progress göstermek isterseniz gerekli olacak.

yml dosyalarını açıp baktığınızda da alttaki gibi olduğunu görebilirsiniz

version: 1.1.3
files:
  - url: appName.exe
    sha512: 1700c55866fab0d0182f35a337c279c29732303e72a506b2f1d9cdfbf7f14b9dcc3831c2d3ef573829697b66f6e06d2cb55967be1ab34cccb354ba10c5b995af
    size: '160272216'
    isAdminRightsRequired: true
path: appName.exe
sha512: 1700c55866fab0d0182f35a337c279c29732303e72a506b2f1d9cdfbf7f14b9dcc3831c2d3ef573829697b66f6e06d2cb55967be1ab34cccb354ba10c5b995af
releaseDate: '2024-09-16T13:57:55.000Z'

yada upload ettiğiniz yml dosyalarını browser üzerinden erişip bakabilirsiniz.

Buraya kadar config ve upload işlemlerimiz tamamsa işlemler electron tarafından kontrol edilmesi, bildirim ve download işlemleri ile ilgili kodları da kısa kısa ekliyorum.

electron tarafında herşeyin otomatik olması sağlanırken tüm adımları teker teker de yaptırabilirsiniz, otomatik dediğim kendisi bir bildirim gösteriyor, download ediyor ve kapatıp açıldığında güncelleniyor, bu yaklaşım ve adım adım kendinizin yöenttiği update işlemleri için methodlar ve eventlar mevcut

electron main.js veya projenizde bu background.js olarakda geçebilir

otomatik kullanım

const {app, BrowserWindow, Menu} = require('electron');
const log = require('electron-log');
const {autoUpdater} = require("electron-updater");

autoUpdater.logger = log;
autoUpdater.logger.transports.file.level = 'info';
log.info('App starting...');

let win;

function sendStatusToWindow(text) {
  log.info(text);
  win.webContents.send('message', text);
}
function createDefaultWindow() {
  win = new BrowserWindow({
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false
    }
  });
  win.webContents.openDevTools();
  win.on('closed', () => {
    win = null;
  });
  win.loadURL(`file://${__dirname}/version.html#v${app.getVersion()}`);
  return win;
}

// ###### auto update dinleme işlemlerini tanımlıyoruz
autoUpdater.on('checking-for-update', () => {
  sendStatusToWindow('Günccele kontrol ediliyor...');
})
autoUpdater.on('update-available', (info) => {
  sendStatusToWindow('Güncelleme mevcut.');
})
autoUpdater.on('update-not-available', (info) => {
  sendStatusToWindow('Güncelleme mevcut değil.');
})
autoUpdater.on('error', (err) => {
  sendStatusToWindow('Error in auto-updater. ' + err);
})
autoUpdater.on('download-progress', (progressObj) => {
  let log_message = "Download hızı: " + progressObj.bytesPerSecond;
  log_message = log_message + ' - Yüzde ' + progressObj.percent + '%';
  log_message = log_message + ' (' + progressObj.transferred + "/" + progressObj.total + ')';
  sendStatusToWindow(log_message);
})
autoUpdater.on('update-downloaded', (info) => {
  sendStatusToWindow('indirme işlemleri tamamlandı');

  // ####kapatılması ve güncellenmesi için alttaki satırları açabilirsiniz veya burayı bir confirm dialog içerisinde işleyebilirsiniz
  /*
  autoUpdater.quitAndInstall(false, true);
  app.quit();
  */

});

app.on('ready', function() {
  createDefaultWindow();

  // ####### control etmesini ve varsa indirmesini istiyoruz
  autoUpdater.checkForUpdatesAndNotify();
});

app.on('window-all-closed', () => {
  app.quit();
});

En basit hali ile örneklemeye çalıştım, bu işlemleri siz adım adım yaptırmak isterseniz bazı ayarlamaları yapmanız gerekiyor, bu ayarlar içerisinde en hassas olanı updater bir güncelleme bulursa bunu otomatik olarak indirmeye başlar bunu devre dışı bırakmak için alttaki kodu yukardaki kod üzerinde dinleme yaptığımız yerin üzerine ekleyin

autoUpdater.autoDownload = false;

bu kodu eklediğimizde autoUpdater.checkForUpdatesAndNotify() isimli method halen otomatik indirmeye başlayabilir bunun yerine autoUpdater.downloadUpdate() bu methodu tetiklememiz gerekir. autoUpdater.downloadUpdate() bu method normalde autoUpdater.autoDownload = false; olarak işlenmediği sürece çalışmayacaktır bu yüzden false eşitlediğinizden emin olun.

json dosyanızda publish ayarlarını programsal bir şekilde uygulamak veya autoUpdater yml veya uygulama dosyalarına erişirken üst bilgiler(headers) eklemek isterseniz alttaki gibi uygulayabilirsiniz


autoUpdater.requestHeaders = {
    osType: os.type(),
    currentVersion: app.getVersion(),
    'X-Force-HTTP-Version': '1.1',
};
autoUpdater.setFeedURL({
    provider: 'generic',
    url: process.env.UPDATE_URL+'/updates',
    requestHeaders: autoUpdater.requestHeaders
});

alttaki yeniden başlatma kodu hakkında da kısa bir bilgi verip yazımı tamamlamak istyiorum

autoUpdater.quitAndInstall(false, true);

parametreler 1. parametre güncellemenin sessiz bir kurulum olup olmayacağını, 2. parametrede güncelleme işleminden sonra uygulamanın tekrar açılısınmı, açılmasınmı seçimini yapmanızı sağlıyor, her ne kadar moacos da çalışmasada.

Daha fazla detay: https://www.electron.build/auto-update

Burda ara