※ このブログはヌーラバー ブログリレー 2021 15日目の記事です。明日は Johnny さんの記事です。
sandboxが有効なElectronアプリをWindows仮想マシンのネットワークドライブ上に置いたソースコードから起動できないというニッチすぎる現象の解決方法について紹介します。調査の経緯を長々と書いてますが、結果だけ知りたいかたは末尾まで一気にスクロールしてください。
目次
経緯
運用中のアプリケーションを最新のelectron 16.xにアップグレードしました。以下のようなpackage.jsonを定義しています。
{ "scripts": { "start": "electron src $NODE_DEBUG_OPTION" }, "devDependencies": { "electron": "16.x", } }
デバッグ時は npm start でローカルのソースコードから起動しています。普段はmacOS上のエディタで開発しているため、macOS上にParallelsでWindows仮想環境を構築し、macOS上のディレクトリをWindows上にマウントしネットワークドライブを割り当てて開発しています。ところがWindowsで以下にのようにGoodbyeの捨て台詞とともに起動直後に強制終了するようになってしまいました。
PS Y:\\app> npm start production > start > electron src $NODE_DEBUG_OPTION [5552:1213/162100.058:ERROR:gpu_process_host.cc(962)] GPU process launch failed: error_code=18 [5552:1213/162100.074:ERROR:gpu_process_host.cc(962)] GPU process launch failed: error_code=18 ... [5552:1213/162100.790:FATAL:gpu_data_manager_impl_private.cc(417)] GPU process isn't usable. Goodbye.
調査開始
調査したところElectron x ネットワークドライブ x Windows x sandboxの組み合わせで問題があることが分かり、さらにそれはChromium自体に起因していました。
- https://github.com/electron/electron/issues/21713
- https://bugs.chromium.org/p/chromium/issues/detail?id=103902#c27
sandboxを無効にしてみる
試しに app.commandLine.appendSwitch(‘no-sandbox’) でsandboxを無効にすると確かに起動するようになりました。しかしセキュアにするためのsandboxなので、たとえ開発時だとしても無効にはしたくありません。
ソースコードをCドライブにコピーしてみる
次に起動時間が長くなりそうなので避けたかったのですが、 npm run start:win を作成し、実行前にネットワークドライブからアプリの全ソースをCドライブにコピーしてから実行してみました。
{ "scripts": { "start:win": "robocopy . %LOCALAPPDATA%\\\\app /e /xd .git /xd dist & electron %LOCALAPPDATA%\\\\app\\\\src $NODE_DEBUG_OPTION"" } }
まあこれで動くと思ったのですが、なんと結果が変わりませんでした。よく考えてみると上記コマンドではソースコードはCドライブにコピーしていますが、electronの実行アプリケーションについてはnpm installでネットワークドライブにあるソースコード直下にインストールされたものが利用されたままです。ここでようやく気づいたのですが、Chromiumに起因しているということはelectronの実行アプリケーションさえネットワークドライブ上で実行しなければいいのでは?と考えました。
結果
というわけでElectron x ネットワークドライブ x Windows x sandboxで問題になる場合は、package.jsonでインストールしたものではなく、electronをグローバルにインストールして、それを使って起動すれば問題なく実行できました。
PS Y:\\app> npm install -g electron PS Y:\\app> electron src $env:NODE_DEBUG_OPTION
もう少しイケてる方法があれば良いのですが、もっと調査するコストと見合わなかったので今回はこの件をブログとREADMEに書いて終わろうかと思います。それでは。