flow-flow-flow

[Electron] electron-builderでビルドした.exeファイルからdefenderアイコン(盾マーク)を外したい

f:id:thegriftsense:20210908000357j:plain

やりたいこと

Electronでビルドした.exeを、自動アップデート処理のためElectronアプリから実行しないといけなくなったけど、 アプリにdefenderアイコンが付いてるせいでwindow.require('child_process').execFile(path)で実行できなかった。 defenderアイコンがついていない.exeは実行できていたので、defenderアイコンをなくせばうまくいくはずだと考えた。

エラー内容

読んでもよくわからないエラー。とにかく.exeを実行できない。

index.js:1 ERROR Error: spawn C:\my-app\exec\installer.exe EACCES
    at Process.ChildProcess._handle.onexit (internal/child_process.js:264)
    at onErrorNT (internal/child_process.js:456)
    at processTicksAndRejections (internal/process/task_queues.js:80)

調査

ググる

エラー内容でググっていたら「ファイルの権限の問題では?」みたいな記事が出てきたのでアクセス権を変えて試してみたけどだめだった。

.exeのアイコンにくっついている盾マークに気づく

そういえば自分がビルドしたアプリにいつからか盾マークがつくようになった。バージョンをさかのぼって盾マークのない.exeをビルドして、その.exeをアプリからwindow.require('child_process').execFile(path)で実行するとちゃんと実行できた。この盾マークのせいか? というかなんで途中からこの盾マークがくっつくようになってるんだ? git checkoutnpm run build を繰り返してどこのコミットから盾マークがつくようになったのか特定する。特定した。URLスキーマからアプリを起動するために入れた処理が原因だった。

原因

URLスキーマからアプリを起動したいという仕様があって、Electron を Custom URL Scheme で起動するこの記事を参考に実装したけど、どうやらこの実装方法の package.json"perMachine": true という記述で盾マークがつくようになるらしい。

"build": {
    ...
    "nsis": {
      "include": "build/installer.nsh",
      "perMachine": true
    },
   ...
}

元凶はわかったとはいえ、この記述はURLスキーマからアプリを起動するために必要な処理なので外すことはできない。詰んだと思いながらも、URLスキーマからアプリを起動する別の方法はないか調べてみると出てきた。しかもElectronのドキュメント。Electron Documentation

解決策

app.setAsDefaultProtocolClient(protocol[, path, args])という関数一行で実装できるらしい。 Electronに関数用意してあるんかーい。ありがとうございます。 原因だったpackage.jsonの記述を消して、Electronが用意してくれている関数でURLスキーマからアプリを開く処理を実装。

app.setAsDefaultProtocolClient('my-protocol');

実際にメインプロセスに記述してビルド。 .exeに盾マークはない。 適当にhtml作って<a src="my-protocol://">アプリ起動テスト</a>書いて起動テスト。 ちゃんとURLスキーマからアプリ起動できたーーーー!

これでURLスキーマからアプリを開ける、盾マークのない.exeができました!

windows defender が嫌い。

参考

Electron Documentation