Mac環境のElectronでWindowsインストーラーとアップデートに対応させる
作成したEelctronアプリをWindowsのインストーラーでインストールできるようにします。さらに、アプリを起動したときにアップデートがあれば、アップデートするようにしてみます。
ディレクトリ構成
sample/
├─ app/
│ ├─ dev/ アプリには含めないモジュール(SCSSのコンパイルなど)
│ └─ src/ アプリ本体
├─ build/ パッケージ化されたアプリ
└─ release/ インストーラー形式のアプリ
こんな感じでフォルダを作成してください。
サンプルアプリの作成
npm init -y
sample/app/srcに移動して、ターミナルコマンドを入力します。
{
"name": "sample",
"version": "0.0.1",
"description": "",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
name
を "sample"
、version
を "0.0.1"
に、main
を "main.js"
に変更します。
sample/
├─ app/
│ ├─ dev/
│ └─ src/
│ ├─ index.html
│ ├─ main.js
│ └─ package.json
├─ build/
└─ release/
srcフォルダにindex.htmlとmain.jsを追加します。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>electron</title>
</head>
<body>
<b>Hello World! v0.0.1</b>
</body>
</html>
// モジュール
var electron = require('electron');
var app = electron.app;
var BrowserWindow = electron.BrowserWindow;
var dialog = electron.dialog;
// メインウィンドウ
var mainWindow;
// 全てのウィンドウが閉じたら終了
app.on('window-all-closed', function() {
if (process.platform != 'darwin') {
app.quit();
}
});
// Electronの初期化後に実行
app.on('ready', function() {
// メイン画面の表示
mainWindow = new BrowserWindow({
width: 800,
height: 600
});
mainWindow.loadURL('file://' + __dirname + '/index.html');
//ウィンドウが閉じたらアプリを終了
mainWindow.on('closed', function() {
mainWindow = null;
});
});
アプリの起動
cd ../
electron src
cd ../
で1つ上の階層へ移動し、electron src
でsrcフォルダ内のアプリを起動します。
アプリの終了
デフォルトだとMacでは左上の赤丸ボタンをクリックしてもアプリは終了しません。ターミナル上でCtrl+Cで終了するか、アプリ上でCommand+Qで終了させます。
アプリのパッケージ化
Windowsインストーラーを作成する前に、まずはパッケージ化する必要があります。
npm init -y
今度は、sample/app/devフォルダに移動し、コマンドを入力します。すると、package.jsonが作成されますが、今回は特に編集はしません。
gulpの導入
npm install gulp -g
gulpをインストールしていなければします。
gulp -v
[16:12:36] CLI version 3.9.1
[16:12:36] Local version 3.9.1
バージョンが表示されていればインストールできています。
electron-packagerの導入
npm install electron-packager --save-dev
アプリをパッケージ化するツールを導入します。依存ライブラリとして wineをインストールする必要があるかもしれませんが、ターミナルに表示される通りに依存ライブラリをインストールしていけば問題ありません。
gulpfile.jsの作成
sample/
├─ app/
│ ├─ dev/
│ │ ├─ gulpfile.js
│ │ └─ package.json
│ └─ src/
│ ├─ index.html
│ ├─ main.js
│ └─ package.json
├─ build/
└─ release/
gulpfile.jsを作成します。
var gulp = require('gulp'),
packager = require('electron-packager');
gulp.task('packager', function(done) {
packager({
dir: '../src', // アプリ本体のフォルダ
out: '../../build', // 出力先のフォルダ
name: 'sample', // アプリ名
arch: 'x64', // 32bit/64bit
platform: 'win32', // OS
electronVersion: '1.7.9', // Electronのバージョン
overwrite: true // すでにフォルダがある場合は上書き
});
});
他にもオプションはたくさんありますが、最低限これでいいと思います。
electron -v
v1.7.9
electronVersion
が分からなければ、このコマンドで表示されます。
タスクの実行
gulp packager
このコマンドを入力すると、sample/buildフォルダ内にsample-win32-x64というフォルダが作成されます。この中のsample.exeをクリックすればアプリを起動することができます。
Windowsインストーラーの作成
npm install electron-winstaller --save-dev
再び、sample/app/devフォルダでコマンドを実行します。Windowsインストーラー形式で書き出せるツールをインストールします。
var gulp = require('gulp'),
packager = require('electron-packager'),
electronInstaller = require('electron-winstaller');
gulp.task('packager', function(done) {
packager({
dir: '../src',
out: '../../build',
name: 'sample',
arch: 'x64',
platform: 'win32',
electronVersion: '1.7.9',
overwrite: true
});
});
gulp.task('installer', function() {
electronInstaller.createWindowsInstaller({
appDirectory: '../../build/sample-win32-x64',
outputDirectory: '../../release',
description: 'description...',
authors: 'Takamasa',
exe: 'sample.exe'
});
});
gulpfile.jsに追記します。
色々なオプションがあるので一度目を通しておくといいと思います。
gulp packager
gulpコマンドを実行しますが、Mac上ではうまく動きませんでした。なので、Parallelsを使ったWindows仮想環境上で実行するとうまくいきました。
gulp-sassをプロジェクトで使用している場合、Macのnode-sassとWindowsのnode-sassが干渉してしまったので、electron-packagerとelectron-winstallerだけ別のgulpfile.jsで管理するといいかもしれません。
sample/
├─ app/
│ ├─ dev/
│ │ ├─ gulpfile.js
│ │ └─ package.json
│ └─ src/
│ ├─ index.html
│ ├─ main.js
│ └─ package.json
├─ build/
│ └─ sample-win32-x64/
└─ release/
├─ RELEASES
├─ Setup.exe
├─ Setup.msi
└─ sample-0.0.1-full.nupkg
sample/releaseフォルダに4つのファイルが出力されます。Setup.exeを実行すればインストーラーが起動し、インストールが始まります。インストール中に表示される緑色のGIF画像はオプションで変更することができます。
インストールすることはできますが、1つ問題があります。それは、アプリ起動のショートカットがデスクトップに追加されないということです。そのため、2回目以降アプリを起動することができません。
デスクトップにショートカット追加
npm install electron-squirrel-startup --save
sample/app/srcフォルダでコマンドを実行します。このパッケージは自動的にデスクトップにショートカットを追加してくれるものです。
// デスクトップにショートカットアイコン追加
if (require('electron-squirrel-startup')) return;
そして、main.jsの一番上に追加します。これで、パッケージ化とインストーラーの作成を行えば、インストール時にショートカットが追加されるようになります。
自動アップデート
アップデート機能を追加
const autoUpdater = electron.autoUpdater;
autoUpdater.setFeedURL('https://アップロードしたURL/update');
autoUpdater.checkForUpdates();
autoUpdater.on("update-downloaded", () => {
index = dialog.showMessageBox({
message: "アップデートあり",
detail: "再起動してインストールできます。",
buttons: ["再起動", "後で"],
noLink: true
});
if (index === 0) {
autoUpdater.quitAndInstall();
}
});
autoUpdater.on("update-not-available", () => {
dialog.showMessageBox({
message: "アップデートはありません",
buttons: ["OK"]
});
});
autoUpdater.on("error", () => {
dialog.showMessageBox({
message: "アップデートエラーが起きました",
buttons: ["OK"]
});
});
gulpfile.jsにアップデート機能を追加します。アップロードしたURLは、後述する処理を行ってから入力します。
v0.0.2を作成
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>electron</title>
</head>
<body>
<b>Hello World! v0.0.1</b>
<b>Hello World! v0.0.2</b>
</body>
</html>
バージョンアップされたことが分かるように書き換えておきます。
{
...
"version": "0.0.1",
"version": "0.0.2",
...
}
sample/app/srcのpackage.jsonのバージョンを0.0.2にします。
そして、パッケージ化とインストーラーを作成します。
サーバーにアップロード
update/
├─ RELEASES
└─ sample-0.0.2-full.nupkg
RELEASESとsample-0.0.2-full.nupkgのファイルをupdateフォルダの中に入れてレンタルサーバー等にアップロードしてください。
autoUpdater.setFeedURL('https://アップロードしたURL/update');
フォルダ名はupdateである必要はありませんが、変更する場合は setFeedURL()
の /update
部分も変更してください。
実際の挙動

アプリを起動してしばらくすると、このようなメッセージボックスが出てきます。再起動を選択すればすぐにバージョンアップが行われます。後でを選択すると、アプリを終了後にアップデートされ、次回起動時には最新版になっています。つまり、どちらの選択肢でもアップデートされます。
アップデートするかどうかをユーザーに任せるなら、最新版かどうかを返すAPIを作成して、ユーザーがアップデートするという選択をしたら autoUpdater.checkForUpdates();
を実行するという風にすれば実装できます。
CSS本執筆しました!!!
CSS本出します!1/29発売予定
— たかもそ@CSS本1/29発売!! (@takamosoo) 2018年12月31日
自分がCSS学びたての頃にもっとはやく知りたかったテクニックを載せています。CSSの基礎知識について解説していないので、中級者〜向けとなります。CSS入門書を読んではみたものの、思い通りに作れない人にオススメです。
よろしくお願いします。https://t.co/fkz1dM03Pj pic.twitter.com/suYyaPqwIs