Electron を使って Photoshop 用 Extension のインストーラを作る


#はじめに

Photoshop CC 2015 より Adobe の方針で ExtensionManager がサポートされなくなったため、どうにもインストールが面倒くさい。
公式では [Adobe Add-ons](https://creative.adobe.com/addons) を推奨していたが、正しく動作せず断念した。
（インストールボタンを押してもなぜかインストールされない...）

そこで Electron の勉強がてらインストーラを作ってみることにする。

#手順

## アプリの下準備

Electron の雛形アプリを作成する。

```sh
git clone https://github.com/electron/electron-quick-start
cd electron-quick-start
npm install
```

適当な場所にインストールさせたい zxp を置く。

```sh
.
├── LICENSE.md
├── README.md
│
│ # こんな感じにエクステンションを設置する。
├── extension
│   └── extension.zxp 
│
├── index.html
├── main.js
├── node_modules
├── package.json
└── renderer.js
```

Adobe からインストール用の [ツール] (https://www.adobeexchange.com/resources/28)を手にいれる。
適当な場所にツールを置く。

```sh
.
├── LICENSE.md
├── README.md
│
│ # こんな感じで設置する。
├── bin
│   ├── mac # Mac用
│   │   └── Contents
│   └── win # Win用
│       ├── ExManBridgeTalkCmd.exe
│       ├── ExManCmd.exe
│       ├── ExManCoreLib.dll
│       ├── ExManCoreLib.lib
│       ├── ExManEscalatedPrivilegeServer.exe
│       ├── ExManZxpSign.dll
│       ├── IMSLib.dll
│       ├── VulcanMessage4.dll
│       ├── XManConfig.xml
│       ├── adobe_caps.dll
│       ├── libeay32.dll
│       └── ssleay32.dll
│
├── extensions
│   └── extension.zxp
├── index.html
├── main.js
├── node_modules
├── package.json
└── renderer.js
```


## 処理の実装

インストール用の処理を追加する。

```index.html
<!-- インストールボタンを設置する -->
<button type="button" onclick="window.install()">インストール</button>
```

```renderer.js
const {ipcRenderer} = require('electron');

window.install = function () {
  // インストール処理の開始（メインプロセスに投げる）
  ipcRenderer.send('install');
}

ipcRenderer.on('installed', () => {
  window.alert('インストール成功');
});

ipcRenderer.on('installfailed', () => {
  window.alert('インストール失敗');
});
```

```main.js
const path = require('path');
const {ipcMain} = require('electron');

// 環境ごとのコマンド情報
function cmd () {
  var path;
  switch (process.platform) {
    case 'darwin':
      path = './bin/mac/Contents/MacOS/ExManCmd';
      break;
    case 'win32':
    case 'win64':
      path = './bin/win/ExManCmd.exe';
      break;
  }
  return path;
}

// インストール実行処理
function install (zxpPath, callback, errorCallback) {

  var cmdPrefix = (process.platform == 'darwin') ? '--' : '/';

  var spawn = require('child_process').spawn(
    path.join(__dirname, cmd()), [cmdPrefix + 'install', zxpPath]
  );

  spawn.on('exit',function(code){
    if (code == 0) {
      callback && callback();
    } else {
      errorCallback && errorCallback(code);
    }
  });
}

ipcMain.on('install', (e, args) => {
  install(
    __dirname + '/extension/extension.zxp',
    () => {
      e.sender.send('installed');
    },
    (code) => {
      e.sender.send('installfailed', code);
    }
  );
});
```

## アプリ化

Electron Packager をインストール

```sh
npm install electron-packager -g
```

Electron Packager を使ってアプリ化

```sh
# electron-packager <sourcedir> <appname> --platform=<platform> --arch=<arch> --version=<version>
electron-packager . extension --platform=darwin,win32 --arch=x64 --version=1.2.2
```



#確認

アプリを起動して「インストール」ボタンをクリックするとエクステンションがインストールされる。
機能としては動作しているが、殺風景なので Web 技術使ってページを装飾してやると良さげ。

![install-screenshot.png](https://qiita-image-store.s3.amazonaws.com/0/56504/81414912-63f7-69a5-459b-1c302224be3e.png)