Flat Leon Works

アプリやゲームを作ってます。

【Mac】ブラウザ(HTML)上から任意のプログラムを起動する

通常、ブラウザ上から任意のプログラムを起動することはできないようになっています。これはおそらく安全性のためなので、ブラウザ上から任意のプログラムを起動することは不可能だと諦めていたのですが、最近ついにその方法を発見したので紹介したいと思います。

注意

  • 一部のブラウザしか対応していません。SafariFirefoxでは動作を確認しましたが、Vivaldiではダメでした。Chromeは未調査です。

方法

発見した方法というのはURLスキームを使った方法です。URLスキームというのはURLリンクからアプリケーションを起動する仕組みで、iOSでは多くのアプリがURLスキームに対応しています。URLスキームといえばiOSと思っていたのですが、Macにもあるのではと思い調べてみたところ今回の方法が見つかったわけです。

URLスキーム機能だけでは、任意のプログラムの起動はできないのですが、URLスキーム機能を応用することで任意のプログラムを起動できるようになります。具体的には、URLスキームのパラメータをコマンドとして実行するプログラムを用意すればいいのです。これにより、そのプログラム経由で任意のプログラムが起動できるようになります。

手順としては以下のようになります。

  1. URLスキーム経由でコマンド文字列を受け取り、そのコマンドを実行するプログラムを用意する
  2. そのプログラムをURLスキーム経由で起動できるようにする

URLスキーム経由でコマンド文字列を受け取り、そのコマンドを実行するプログラムを用意する

URLスキームに対応したプログラムを作成するには、Macのアプリケーションとして作成する必要があります。大変そうですが、AppleScriptを使えば簡単にMac用アプリケーションを作成することができます。

手順

  1. プログラム名(アプリケーション名)を決める
  2. スクリプトエディタ(/Applications/Utilities/Script Editor.app)」を起動する
  3. AppleScriptのコードを入力する
  4. アプリケーションとして書き出す

プログラム名(アプリケーション名)を決める

まずプログラム名を決めます。URLスキームとしての名前にもなることを考えて決めましょう。この記事では「URLSchemeExec」という名前にします。URLスキームとしては、「URLSchemeExec://」または「urlschemeexec://」という感じで利用することになります。

スクリプトエディタ(/Applications/Utilities/Script Editor.app)」を起動する

スクリプトエディタを起動し「新規書類」を選ぶと、こんな画面が出るはずです。

AppleScriptのコードを入力する

以下のコードを入力します。"URLSchemeExec://"の部分は、先程決めたプログラム名に書き換えてください。

-- URLスキーム経由で起動したときに呼ばれる関数
on open location url_scheme
    -- URLスキームの先頭部分を除去する("URLSchemeExec://"の部分は、先程決めたプログラム名にする)
    set AppleScript's text item delimiters to {"URLSchemeExec://"}
    set txt_items to text items of url_scheme
    set AppleScript's text item delimiters to {""}
    set scheme_txt to txt_items as Unicode text

    -- URLエンコード(%エンコード)を元に戻す
    set scheme_txt2 to urlDecode(scheme_txt)

    -- Terminalを起動する
    tell application "Terminal"
        activate
        -- コマンドをTerminal上で実行する
        do script scheme_txt2
    end tell
end open location

on urlDecode(str)
    set temp to "php -r 'echo rawurldecode(" & quote & str & quote & ");'"
    return (do shell script temp) as string
end urlDecode

アプリケーションとして書き出す

「ファイル -> 書き出す」で書き出してください。このときファイルフォーマットの指定に「アプリケーション」を選んでください。

これで、「URLスキーム経由でコマンド文字列を受け取り、そのコマンドを実行するプログラム」が用意できました。

プログラムをURLスキーム経由で起動できるようにする

先程作ったアプリケーションは、URLスキーム呼び出し時の処理は実装されていますが、実際にURLスキーム経由で起動できるようにはなっていません。これをできるようにするには、アプリケーション内のinfo.plistを書き換える必要があります。info.plistはアプリケーションバンドル内のURLSchemeExec.app/Contents/Info.plistにあります。バンドル内に入るには「URLSchemeExec.app」のコンテキストメニューから「パッケージの内容を表示」を選びます。

info.plist を書き換える

以下のコードを追加します。「URLSchemeExec」の部分は最初に決めたプログラム名に置き換えてください。

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLName</key>
        <string>com.apple.ScriptEditor.id.URLSchemeExec</string>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>URLSchemeExec</string>
        </array>
    </dict>
</array>

アプリケーションを起動して、URLスキームを認識させる

URLスキームをOS側に認識させるために、一度アプリケーションをダブルクリックで起動します。ただし起動しても、URLスキーム対応以外のコードを書いていないので何も起こらないはずです。

これでURLスキームから任意のプログラムを実行する準備ができました。

実際にブラウザ上から任意のプログラムを起動させてみる

実際にURLスキームを試すには、ブラウザのアドレスバーに入力するのが手っ取り早いです。アドレスバーに以下のように入力してみて、正しく動作するかどうか確認してみましょう。

URLSchemeExec://echo aaa

Safariの場合、空白があるとURLスキームと認識されないようなので以下のようにする必要があります。

URLSchemeExec://echo%20aaa

ターミナルが起動して、「aaa」と出力されたら成功です。

ターミナルを起動せずにプログラムを実行する

上記のAppleScriptはターミナル経由でプログラムを起動していましたが、ターミナルを出さずにプログラムを起動させたい場合はAppleScriptコードを以下のようにします。別名のアプリケーションとして用意しておくよいかもしれません。

-- URLスキーム経由で起動したときに呼ばれる関数
on open location url_scheme
    -- URLスキームの先頭部分を除去する("URLSchemeExec://"の部分は、先程決めたプログラム名にする)
    set AppleScript's text item delimiters to {"URLSchemeExec://"}
    set txt_items to text items of url_scheme
    set AppleScript's text item delimiters to {""}
    set scheme_txt to txt_items as Unicode text

    -- URLエンコード(%エンコード)を元に戻す
    set scheme_txt2 to urlDecode(scheme_txt)

    -- プログラムを起動する
    do shell script scheme_txt2
end open location

on urlDecode(str)
    set temp to "php -r 'echo rawurldecode(" & quote & str & quote & ");'"
    return (do shell script temp) as string
end urlDecode

まとめ

以上、URLスキームとAppleScriptの組み合わせでブラウザから任意のプログラムを起動できるようになるという話でした。ブラウザから任意のプログラムが起動できて何が嬉しいのかというと、HTMLがより便利なフォーマットになることです。例えば、ローカルHTMLを使ってプログラムランチャーあるいはファイルランチャーのようなものを作ることができるようになります。HTMLを使ってランチャーを作ると、自由なレイアウトでリンクを配置したり、画像を貼ったり、プログラムの説明を記述したりといったことが可能になります。また、ドキュメントを記述する際にファイルやフォルダの場所を記述ことはよくあると思いますが、HTMLを使ってドキュメントを作成すれば、openコマンドを使ってドキュメント上から直接ファイルやフォルダを開けるようになります。

今回紹介した方法はMacでしかできない方法ですが、URLスキーム自体はWindowsにもあるようなのでもしかしたら似たような方法でWindowsでも可能かもしれません。-> ASCII.jp:WindowsでURLのプロトコルからアプリを起動する|Windows Info

参考にしたサイト