質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Electron

Electronは、HTML5とNode.jsというWebの技術を用いてデスクトップアプリケーションを作成できるクロスプラットフォームな実行環境です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

4591閲覧

Electronアプリが異常終了します

workr

総合スコア158

Electron

Electronは、HTML5とNode.jsというWebの技術を用いてデスクトップアプリケーションを作成できるクロスプラットフォームな実行環境です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2017/01/18 03:58

編集2017/02/08 08:21

Mac上のElectronでアプリケーションを作って実行していると、数分でトレイアイコンが消えるなどの異常が見られ、コンテキストメニューから項目を選ぶとクラッシュします。
クラッシュ時には「Electron が予期しない理由で終了しました。」とダイアログが出ます。
実行中のデベロッパーツールのログにはとくにエラーは記録されていませんでした。
エラーレポートには次のように書かれていました。(長文のため抜粋)

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x00007f9700000249

以下が最小限まで切り落としたプログラムソースです。

index.js

Javascript

1'use strict'; 2 3const electron = require('electron'); 4const app = electron.app; 5const BrowserWindow = electron.BrowserWindow; 6 7var mainWindow = null; 8app.on('ready', function() { 9 mainWindow = new BrowserWindow({ 10 "width": 800, 11 "height": 600 12 }); 13 14 mainWindow.loadURL('file://' + __dirname + '/index.html'); 15 mainWindow.openDevTools(); 16 17 mainWindow.on('closed', function() { 18 mainWindow = null; 19 }); 20});

index.html

JavaScript

1<!DOCTYPE html> 2<html> 3 <head> 4 <meta charset="utf-8"> 5 <title>Sample</title> 6 <script> 7 const remote = require('electron').remote; 8 const Menu = remote.Menu; 9 const MenuItem = remote.MenuItem; 10 const Tray = remote.Tray; 11 const NativeImage = remote.nativeImage; 12 13 document.addEventListener('DOMContentLoaded', function(){ 14 var contextmenu = new Menu(); 15 contextmenu.append( 16 new MenuItem({ 17 label: 'Quit', 18 click: function() { 19 remote.app.quit(); 20 } 21 }) 22 ); 23 24 window.addEventListener('contextmenu', function(ev) { 25 ev.preventDefault(); 26 try { 27 contextmenu.popup(ev.x, ev.y); 28 } catch(e) { 29 console.log(e); 30 } 31 return false; 32 }, false); 33 34 var icon = NativeImage.createFromPath(__dirname + '/icon.png'); 35 36 var tray = new Tray(icon.resize({ 37 width: 18, 38 height: 18 39 })); 40 tray.setContextMenu(contextmenu); 41 42 run(); 43 44 function run(){ 45 window.requestAnimationFrame(function(){ 46 run(); 47 }) 48 } 49 }); 50 </script> 51 </head> 52 <body> 53 test 54 </body> 55</html>

実行するとウィンドウとトレイアイコンが表示され、コンテキストメニューから終了することが出来ます。
しかし、数分するとトレイアイコンが消え、ウィンドウのコンテキストメニューから終了を選ぶと必ずクラッシュします。
本来はrequestAnimationFrame()を利用した時計を作る予定でした。
Electron 1.4.13 を OS X 10.11.6 で利用しています。

何が問題の原因なのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

workr

2017/01/19 09:07

index.jsの基本的な動作は提示いただいたmain.jsのコードとほぼ同じになっています。index.jsをそちらに差し替えても症状に変化はありませんでした。
guest

回答1

0

ベストアンサー

概要

DOMContentLoadedイベントのハンドラ内で変数をvarで宣言しているので関数スコープになってしまい、ハンドラ終了後ガベージコレクタの対象となり一定時間後に破棄され、例外発生となっています。

ハンドラ内のvarだけ削除して、宣言は外で行えばいいかと思います。

コード

  • index.js

javascript

1const {app, BrowserWindow} = require("electron"); 2 3var mainWindow = null; 4 5app.once("ready", () => { 6 mainWindow = new BrowserWindow(); 7 mainWindow.loadURL("file://" + __dirname + "/index.html"); 8 mainWindow.openDevTools(); 9 10 mainWindow.on("closed", () => { 11 app.quit(); 12 }); 13});
  • index.html

javascript

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4 <meta charset="UTF-8"> 5 <title>sample</title> 6</head> 7<body> 8 <h1>sample</h1> 9 <script> 10 const {remote} = require("electron"); 11 const {Menu, Tray, nativeImage, MenuItem} = remote; 12 13 var contextmenu, icon, tray; 14 15 document.addEventListener("DOMContentLoaded", () => { 16 contextmenu = new Menu(); 17 icon = nativeImage.createFromPath(__dirname + "/icon.png"); 18 19 contextmenu.append( 20 new MenuItem({ 21 label: "Quit", 22 click: () => { 23 remote.app.quit(); 24 } 25 }) 26 ); 27 28 window.addEventListener("contextmenu", (event) => { 29 event.preventDefault(); 30 try { 31 contextmenu.popup(event.x, event.y); 32 } catch(e) { 33 console.log(e); 34 } 35 return false; 36 }, false); 37 38 tray = new Tray(icon.resize({ 39 width: 18, 40 height: 18 41 })); 42 tray.setContextMenu(contextmenu); 43 }); 44 </script> 45</body> 46</html>

投稿2017/02/17 04:17

編集2017/02/17 04:20
StupidDog

総合スコア263

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

workr

2017/02/20 01:10

教えていただいた方法で無事にエラーが出なくなりました。回答ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問