electronにはautoUpdaterと呼ばれる仕組みが用意されていますが、非常に複雑な上に場合によってはコードサイニングが必要である(その割には、やることがアップデートだけ・・・)という事で、社内で使うにはちょっと面倒。

また、Mac向けとWindows向けで手法が異なる。という事で、外部向けではないのであれば、面倒な手法など使わずこれまでのようなクラシックな手法でアップデートできたら良いな、と考えAccessのアプリのアップデータ配布と同じような手法を装備してみた。

今回準備するもの

  • アップデータ本体であるexeファイルやdmgファイル
  • アップデート情報の入ったファイルもしくは、MySQLサーバのテーブルとデータ
  • exeファイルを置けるファイルサーバやWebサーバ

今回のケースでは、MySQLサーバの特定のテーブルにある「バージョン情報」と、自身のバージョン情報を照合し、新しいバージョンがある場合には、対象のファイルをダウンロード、自動実行の後、再びアプリを起動するという手法を取っています。MySQLがなくともJSONやXMLといったファイルをダウンロードして、バージョン情報を取得する方法でも良いでしょう。

今回、Windows向けという事で、Exepress6にてインストーラを作成しています。インストール後にアプリ本体のexeを自動実行するように設定を施してありますので、アプリの自動起動自体は設定のみでOKです。

ソースコード

サーバー側コード

サーバ側はNode.jsでMySQLへアクセスし返すように組んでいます。electron側から直接接続でも良いのですが、今回はWeb APIな仕組みで運用しています。別途インストールしてるモジュールは、expresspromise-mysqlの2つです。

  • 接続情報であるUser IDとPASSワードはクライアント側から送ります。
  • settingテーブルは、ID, value, textの3列だけです。valueにはバージョン情報、textにはexeファイルまでのURLを入れてあります。
  • settingテーブルのIDが2のレコードがアップデート情報のレコードという事にしてあります。
  • クライアント側からは、POST通信でAPIのやり取りを行っています。

クライアント側コード

クライアント側であるelectronのindex.jsには、起動時にバージョン情報を取得しに行くコードを用意します。node-cronイベントループの仕組みを使ったりして、常時アップデート情報を監視する方法も良いでしょう。

electron側で今回利用する追加モジュールは、requestelectron-storekeytarになります。他にも標準でいくつかのモジュールを利用しています。

  • store.getにて予め保存されているID情報やServer情報を取得します。
  • child_processにてEXEを実行するための準備をしています。ただい、そのまま実行すると、アプリが起動したままインストーラでインストールする事になり、エラーとなるので、別プロセス起動する必要があります。
  • process_envにて、デスクトップのパスを取得させて、既定の保存場所として指定しています。
  • exeファイルまでのURLに対して、requestにてHTTP要求を出し、fsにて指定の場所にダウンロードさせています。
  • runCommandは、child_processを本体のappとは別プロセスとして起動させる為のルーチンです。
  • 別プロセスとして起動させたら、本体のappはapp.quitさせる必要があります。今回は、閉じるとTrayに残る仕様にしていた為、process.exit(0)を呼び出して終了させています。
  • require(‘./package.json’).versionにて、package.jsonのversion情報を取得できます。この値と、サーバ側からのバージョン情報を比較して、アップデートの可否を判定させています。

考察

今回の仕組みは

  1. バージョン問い合わせ
  2. ファイルのダウンロード
  3. インストーラの実行
  4. 自身のプロセスを終了
  5. インストーラでファイル上書き

といった単純なプロセスです。きちんと、package.jsonの場ジョン情報や、サーバ側のバージョン情報をメンテナンスしておく必要があります。完全自動アップデートではありませんが、ほぼ同等のスピードで配布する事が可能です。

関連リンク

共有してみる: