flow-flow-flow

[electron] electronアプリをURLから起動したい

いまやってる案件で、メール本文の「リンクからアプリを起動させたい」という要望がでたので対応するためにやり方を調べたのでメモ。 実装してみるまではできるか不安だったけれど、割と一瞬で実装できたのでよかった。

環境
- electron: 8.5.5
- electron-builder: 22.10.5

MacとWindowsで実装方法が異なるので順番に書いていく。

1. 実装方法 for Mac

Macは本当に一瞬で終わる。

"build": {
  ...
    "protocols": {
      "name": "myApp IM URL",
      "schemes": [
        "my-appname"
      ]
    },
   ...
 }

余談だけれど、上記は参考にした記事にあったサンプルコードで、こういうサンプルコードが出てきた時、自分は「schemeプロパティのmy-appnameのところにはアプリ名をいれればいいんだな。でもnameプロパティのmyApp IM URLのところには何を入れればいいんだよ。つーかnameプロパティの値が普通my-appnameじゃねえのかよ。あああ判りそうで判らん」みたいな、完成されたサンプルコードは目の前にあるのに、任意で値を指定しなといけない部分でつまづいてめちゃめちゃ歯がゆい経験をしたことが数え切れないくらいある。

ふつうにプログラミングできる人からは「ドキュメント読みなさいよ」と一蹴されてしまうような愚痴。

というわけでもう少し変わりやすく書くと、

"build": {
  ...
    "protocols": {
      "name": "myApp IM URL", // ここは自分のアプリ名を記述
      "schemes": [
        "my-appname" // ここにアプリを起動するときのプロトコルを記述。詳しくは後述する
      ]
    },
   ...
 }

という感じである。 nameプロパティの値は、たとえばアプリ名が「hoge」だったら name: "hoge" でOK。 schemesプロパティの値については、まずアプリを起動するときのリンクをどういうふうに作るかの説明が必要で、 サンプルコードのようにschemesプロパティが、schemes: ["my-appname"] だった場合、下記の様なリンクを踏むとアプリが起動する。

<a href="my-appname://">アプリ起動</a>

なのでschemes: ["piyo"] だった場合、href="piyo://"のリンクを踏めばアプリが起動することになる。 いろいろ記事を読んだけど、プロトコル部分はアプリの名前にするのが慣習のようなので、アプリ名がhogeなら、プロトコルもhogeとして、hoge://で起動するようにしておくのがいいと思われる。もちろんプロトコル部分のあとにはpathが指定できる。

Macの実装は以上。 試しにビルドして、下記の様なhtmlを作成してブラウザに表示させて、リンクをクリックしてみるとアプリが起動するはずである。

<a href="hoge://">アプリ起動</a>

こんな画面がでるはず。出れば勝ち。 f:id:thegriftsense:20210713005451p:plain

実装方法 for Windows

次windows。 package.jsonへの記述の他に、ファイルをひとつ作成しないといけないので手数がひとつ増える。 package.json部分はこのままコピペするだけで問題ない。

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

で、includeプロパティで指定している、build/installer.nshを作成してやらないといけない。 これもほぼコピペで、アプリの名前を記述する箇所だけ書き換えればOK。 publicディレクトリ配下のファイルがビルド後にbuild配下に反映されると思うので、ファイルを作成するときはpublicディレクトリ配下にinstaller.nshファイルを作成する。

!macro customHeader
    !system "echo '' > ${BUILD_RESOURCES_DIR}/customHeader"
!macroend

!macro preInit
    ; This macro is inserted at the beginning of the NSIS .OnInit callback
    !system "echo '' > ${BUILD_RESOURCES_DIR}/preInit"
!macroend

!macro customInit
    !system "echo '' > ${BUILD_RESOURCES_DIR}/customInit"
!macroend

!macro customInstall
    !system "echo '' > ${BUILD_RESOURCES_DIR}/customInstall"

    DetailPrint "Register My AppName URI Handler"
    DeleteRegKey HKCR "My AppName"
    WriteRegStr HKCR "My AppName" "" "URL:my-appname"
    WriteRegStr HKCR "My AppName" "URL Protocol" ""
    WriteRegStr HKCR "My AppName" "EveHQ NG SSO authentication Protocol" ""
    WriteRegStr HKCR "My AppName\DefaultIcon" "" "$INSTDIR\${APP_EXECUTABLE_FILENAME}"
    WriteRegStr HKCR "My AppName\shell" "" ""
    WriteRegStr HKCR "My AppName\shell\Open" "" ""
    WriteRegStr HKCR "My AppName\shell\Open\command" "" "$INSTDIR\${APP_EXECUTABLE_FILENAME} %1"
!macroend

!macro customInstallMode
    # set $isForceMachineInstall or $isForceCurrentInstall
    # to enforce one or the other modes.
!macroend

なんのこっちゃ判らんファイルだけど、とりあえず上記をコピペして、My AppName のところを自分のアプリの名称に変更すればOK。 これでwindows側の設定も終わりなので、ビルドして、Macのときのようにリンクを踏んでアプリが起動するかどうか確認する。 起動できれば勝ち。

詰まったところ

これはいっしゅん詰まったところだけど、はじめvscodeでmdファイルを作成してそのmdファイルに(hoge://)[アプリ起動]みたいなかんじでリンクを作成して、プレビューさせて、そのリンクを踏んでアプリ起動の確認をしていた。

うんともすんとも言わなかった。で、htmlファイルを作成してブラウザで読み込んでリンクを踏んだらちゃんとアプリが起動した。 自分以外にそんなことをする人がいるのかも謎だけれど、とりあえずvscodeでプレビューしたmdファイルからのリンクじゃアプリ起動しないよということが言いたかった。

あと、メールでリンクを送る際にhoge://みたいなプロトコルだとリンクが剥がされるみたいだったので、メールをhtml形式にして対応するか、メールにはhttps://のリンクを用意しておいて、開いた先のページでhoge://を踏ませるとか、ちょっと対応が必要そう。

自分の場合はメールをhtml形式にするで落ち着きそう。

おわり!