Help us understand the problem. What is going on with this article?

Electron: autoUpdaterでアプリを自動アップデートさせる方法 (Mac/Windows)

More than 3 years have passed since last update.

TL; DR

  • ElectronのautoUpdaterモジュールを使うとMac/Windowsでアプリを自動アップデートさせられる
  • Mac/Windowsそれぞれ違うアップデートのリリース方法が必要
    • Mac: アップデート情報を返すWeb APIを用意する
    • Windows: grunt-electron-installer で作ったファイルをS3とかにアップロードする
  • あとはautoUpdaterのAPIを呼び出すだけ

はじめに

Electronには autoUpdaterという、アプリの自動アップデート用モジュールが入っている。これを使うとMac/Windowsでアプリを自動アップデートさせることができる。

Wantedlyが開発しているメッセージングアプリのSyncデスクトップ版では、実際にautoUpdaterを使っているが、Mac/Windowsそれぞれで違うセットアップが必要であったりして意外と使うには手間がかかった。

そこで、ElectronのautoUpdaterを使ってMac/Windows上で実際に自動アップデートを行う方法がどうなるかをまとめてみた。

Mac

MacのautoUpdaterには、内部的にSquirrel.Macが使われている。

アプリを署名する

アプリを Developer ID certificate (iOS開発などでApple Developer Program に登録していれば取得できる) で署名する必要がある。
electron-packagerのオプションでも対応している。
署名しないとアップデートのインストールに失敗する。

アプリ (.app) をzip圧縮する

.app を直接zip圧縮する。

zip -r -y myapp-1.0.0.zip myapp.app

Web APIを用意する

https://github.com/Squirrel/Squirrel.Mac#server-support

Squirrel.Macがアップデートをチェックするのに使うWeb APIを用意する。
アップデートがある場合、レスポンスとして、zipファイルのダウンロードURLとメタデータを返す。

リクエスト例
GET releases.myapp.com/latest?version=1.0.0&platform=darwin

パラメータ等はSquirrel.Macが付加するわけではないので自由 (アプリのバージョンなどを元にする)。

レスポンス例 (アップデートあり)

200 OK

レスポンス
{
  "url": "https://url/to/myapp-1.0.1.zip",
  "name": "my release",
  "notes": "my notes",
  "pub_date": "2015-07-01T04:46:15.898Z"
}
レスポンス例 (アップデートなし)

204 No Content

autoUpdater 設定

アップデートチェック用APIのURLをsetFeedURLで設定する。

const {autoUpdater} = require("electron");
autoUpdater.setFeedURL("https://releases.myapp.com/latest?version=1.0.0&platform=darwin");

Windows

Windows上でのautoUpdaterでは Squirrel.Windows が使われているので、それに対応するようアプリをリリースする。

grunt-electron-installer でインストーラとNuGetパッケージ用ファイルをつくる

Squirrel.Windows ではアップロードを確認・ダウンロードするのにNuGetパッケージを使っている。
自前でNuGetパッケージを用意することも出来ると思われるが、 grunt-electron-installer を使うと NuGetパッケージに必要なファイルを自動生成してくれる。
さらに、Atomなどのインストーラと似たようなシンプルでかっこいいインストーラも生成してくれるので便利。

gruntのタスクとして提供されているが、gulpなどから使うことも可能

この際、(特にproductionでは) Authenticode でコード署名をしておく必要がある。
コード署名をしていないと、アプリがマルウェアに誤判定される・ダウンロードしたインストーラを実行するときに怖い警告が表示される、など様々な面倒なことが起こる

設定例

'create-windows-installer': {
  ia32: {
    appDirectory: '/tmp/build/myapp', // electron-packagerなどでパッケージしたアプリのディレクトリ
    outputDirectory: '/tmp/build/installer',
    authors: 'My App Inc.',
    exe: 'myapp.exe'
  }
}
生成されるファイル例

RELEASES: リリース一覧のテキストファイル
Setup.exe: インストーラ
myapp-1.0.0-full.nupkg: アップデートのnupkg

アップロード

生成されたRELEASES / *.nupkg ファイルをそのまま (S3などに) アップロードすることで、NuGetパッケージをホストすることになる(らしい)。
なので、必ずしもアップデート用にサーバを用意する必要はない。

autoUpdater 設定

RELEASES*.nupkgファイルがあるディレクトリをsetFeedURLで設定する。

const {autoUpdater} = require("electron");
autoUpdater.setFeedURL("https://releases.myapp.com/windows");

autoUpdater を使う (共通)

リリースしたアップデートを実際にアプリ側で適用するには、autoUpdater モジュールからアップデート処理を呼び出す必要がある。

checkForUpdates()

autoUpdater.checkForUpdates() を呼び出すとアップデートがチェックされる。アップデートが見つかった場合 即座に ダウンロードが始まる。

quitAndInstall()

アップデートがあった時、autoUpdater.quitAndInstall() を呼ぶと即座にアップデートをインストールして再起動できる。 (呼び出さなくてもアプリの次回の起動時に自動的にインストールされる)

イベント

アップデートのチェック結果ごとに "update-available""update-not-available""error" イベントが来る。
アップデートのダウンロードが終わると"update-downloaded"イベントが来る。

const {autoUpdater} = require("electron");
autoUpdater.setFeedURL(<先ほどのURL>);
autoUpdater.checkForUpdates();

autoUpdater.on("update-downloaded", () => {
  index = dialog.showMessageBox({
    message: "アップデートあり",
    detail: "再起動してインストールできます。",
    buttons: ["再起動", "後で"]
  });
  if (index === 0) {
    autoUpdater.quitAndInstall();
  }
});
autoUpdater.on("update-not-available", () => {
  dialog.showMessageBox({
    message: "アップデートはありません",
    buttons: ["OK"]
  });
});
autoUpdater.on("error", () => {
  dialog.showMessageBox({
    message: "アップデートエラーが起きました",
    buttons: ["OK"]
  });
});

まとめ

プラットフォームごとにセットアップをすると、autoUpdaterを使ってクロスプラットフォームなアプリの自動アップデートを実現できる。
正直面倒な手順なので、将来的に改善されるべきだとは思う(特に、プラットフォームごとにやり方が違うのは良くない)。
一旦セットアップしてしまえば、簡単にユーザに最新のアプリを使ってもらうことができるので便利。

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away