ブラウザ上のリンクから任意のデスクトップアプリのファイルを開けると超便利

# はじめに
本稿は、任意のデスクトップアプリをブラウザ上のリンクをクリックして起動させる方法の紹介です。通常は、ブラウザのリンクからデスクトップアプリは起動できませんが、それをできるようにする方法です。
例えば、`Excel://hogeserver/sample.xlsx` というブラウザ上のリンクをクリックして、sample.xlsx を Excelで開けると、とても便利です。

**2022/3/28 追記**
本稿で紹介しているカスタム URL スキームを用いて、SlackでUNCパスのリンクを開けるようになるツールを以下で公開しています。
[SlackでUNCパスのリンクをクリックして直接ファイルが開けるようになるツール「Liwing」](https://qiita.com/kojimadev/items/1b29dfbae456ba28e6be)


# カスタム URL スキーム
Windowsには、URI スキームという概念があり、特定のアプリはブラウザからでもリンクをクリックすることで起動できます。
例えば、`mailto:` から始まるuriで既定のメールアプリを起動できます。詳細は以下参照。
[URI に応じた既定のアプリの起動 | Microsoft](https://docs.microsoft.com/ja-jp/windows/uwp/launch-resume/launch-default-app)

さらに、上記をカスタマイズするために、カスタム URL スキーム という概念があり、それを用いることで任意のデスクトップアプリを起動できるようになります。
例えば、`note:` でノートパッドを起動できるようにできます。詳細は以下参照。
[カスタム URL スキーム の 設定 と 利用](https://garafu.blogspot.com/2014/02/url.html?m=1)

# 自分が開発したデスクトップアプリをパラメータ指定で起動する
カスタムURLスキームを用いて、自分が開発したデスクトップアプリをパラメータ指定で起動する方法を以下に記します。パラメータはファイルパスとし、そのアプリで指定したファイルを開く想定とします。

まず、事前準備として、以下の記事にあるようにレジストリを設定します。
[カスタム URL スキーム の 設定 と 利用](https://garafu.blogspot.com/2014/02/url.html?m=1)
以下はレジストリを設定するための .reg ファイルの例です。XXX の部分は任意の文字列を設定してください。

```
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\XXX]
@="URL:XXX Protocol"
"URL Protocol"=""

[HKEY_CLASSES_ROOT\XXX\shell\open\command]
@="\"C:\\Program Files\\XXX\\XXX.exe\" \"%1\""
```
上記のレジストリ設定をすることで、`XXX:` というリンクをクリックすると、XXX.exeが実行されます。
また、上記レジストリの "%1" という部分でパラメータを受け取るようにしています。
例えば、`XXX:\\hogeserver\sample.txt` というリンクの場合、XXX.exeに対して "XXX:\\\\hogeserver\\sample.txt" というパラメータが渡されます。(パラメータに渡される引数はブラウザに依存するようです。本稿はChromeで確認した場合のパラメータを記します。)

あとは、XXX.exe が上記のパラメータを解釈できるようにすれば、対象のファイルを開くことができます。
コマンドラインパラメータをファイルパスとして解釈してファイルを開く例として、C#の例を以下に記します。

```c#
// コマンドライン引数を取得
string[] args = Environment.GetCommandLineArgs();

if (arg.StartsWith("XXX:"))
{
	// カスタムURLスキームを取り除いた文字列をファイルパスとみなして取得する
	var filePath = arg.Substring("XXX:".Length);

	// filePathを用いてファイルを開く
	...
}
```

例えば、ブラウザで以下のリンクをクリックした場合、\\\\hogeserver\\sample.txt  のファイルを XXX.exeで開くことができます。

```
<a href="XXX:\\hogeserver\sample.txt">sample.txtへのリンク</a>
```

# 任意のデスクトップアプリをパラメータ指定で起動する
notepadやExcelなどの任意のアプリをパラメータ指定で起動することもできます。
上記の方法でパラメータを取得するデスクトップアプリを作成し、そのパラメータを実行したい任意のアプリ(notepadやExcelなど)に渡して実行すればOKです。
具体例として、`XXX:\\hogeserver\sample.txt` というリンクをクリックした場合に、sample.txtを Notepadで開くC#の例を以下に記します。

```c#
// コマンドライン引数を取得
string[] args = Environment.GetCommandLineArgs();

if (arg.StartsWith("XXX:"))
{
	// カスタムURLスキームを取り除いた文字列をファイルパスとみなして取得する
	var filePath = arg.Substring("XXX:".Length);

	// (ここまでは、前の章のソースコードと同じ)

	// filePathをパラメータに指定して「notepad」でファイルを開く
	Process.Start("notepad.exe", filePath);
}
```
ちなみに既定のアプリでファイルを開くなら、最後の行を Process.Start(filePath); にすればいけると思います。

また、UNCパスでなく、http始まりのファイルをMicrosft Officeで開きたい場合は、本稿の方法ではなく、以下を参照ください。
[Office URI スキーマ | Microsft Docs](https://docs.microsoft.com/ja-jp/office/client-developer/office-uri-schemes)

# Slackと組み合わせると便利
Slack の場合、上記のパスをバックスラッシュ( \\ )でなくスラッシュ( / )にして投稿すると、クリック可能なリンクにして表示してくれます。そのため、アプリ側をバックスラッシュの代わりにスラッシュでも開けるように対応しておくと便利です。
例えば、以下の文字列を Slack に投稿すると、リンク表示されます。
XXX://hogeserver/sample.txt
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403606/131ff46f-246d-a2fe-9603-c7b18c8cd464.png)

ちなみに、Microsoft Teamsでは上記文字列はリンクになりません(残念)。

# まとめ
本稿の方法で作成したアプリとレジストリ設定をチーム内に展開した上で、Slackでそれに対応したURLを投稿すると、任意のデスクトップアプリで任意のファイルがワンクリックで開けるので、とても便利です。

本稿で紹介しているカスタム URL スキームを用いて、SlackでUNCパスのリンクを開けるようになるツールを以下で公開しています。
[SlackでUNCパスのリンクをクリックして直接ファイルが開けるようになるツール「Liwing」](https://qiita.com/kojimadev/items/1b29dfbae456ba28e6be)

Twitterでも開発に役立つ情報を発信しています → [@kojimadev](https://twitter.com/kojimadev)