下書きで一年以上放置しちゃってた。
前回は、ChromeやEdgeで共有フォルダをエクスプローラで開いたり、xlsxをExcelで直接開いたりできるツールを作りました。
このxopenerはもともと、社内で使ってるGitLabのIssueに共有フォルダのリンクを貼りたいよねってところから開発しました。
しかし人間の欲望は際限がないので、Teamsでも同じようにフォルダ開けたら便利だよねなどという話になってしまいました。
ですが、TeamsやDiscordはカスタムURIスキームに対応しておらず、xopener:C:\
という文字列を貼っても開けません。
これは困ったというわけで無理やり開けるようなツールを追加で作ってみました。
GitHub - anseketamen/XOpener: ChromeやEdgeからエクスプローラーを開くツール
ここからは肝になっていそうな部分をざっくり説明していきます。
1. 方法を考えよう
TeamsやDiscordはカスタムURIスキームに対応していません。しかしWeb系(http:やhttps:)は開けるので、一旦httpのページに飛ばして、そこからxopener:
にリダイレクトさせればいいんじゃないかと思いつきました。
というわけで雑にASP.NET CoreのMinimal APIで転送するやつを作って試したらうまくいきました(ソースコードは省略)。
そのままそれでやってもよかったんですが、動かすには.NETランタイムを入れなきゃいけなかったりしたので、前回同様Windowsにもともと入っている機能だけで作り直しました。
2. HTTPを待ち受けて転送しよう
何をやっているかというと、http://localhost:10082/?path=C:\
というURLでアクセスされたら、xopener:c:\
に302リダイレクトします。それだけです。
await writer.WriteLineAsync("HTTP/1.0 302 Found"); await writer.WriteLineAsync("Content-Type: text/plain; charset=UTF-8"); await writer.WriteLineAsync("Location: xopener:" + path); await writer.WriteLineAsync(); await writer.WriteLineAsync("path: " + decodedPath);
3. いい感じのリンクを自動生成できるようにしよう
レジストリをいじくって、エクスプローラーでShift+右クリックすると「XOpener用にパスをコピー」というメニューが出るようにしましょう。
↓みたいな感じのやつを、「ファイル選択時」「フォルダ選択時」「フォルダの何もないとこ選択時」「ドライブ選択時」の4パターン作ります。
[HKEY_CURRENT_USER\SOFTWARE\Classes\*\shell\XOpener] @="XOpener用にパスをコピー" "Extended"="" [HKEY_CURRENT_USER\SOFTWARE\Classes\*\shell\XOpener\command] @="\"C:\\xopener\\helpers\\xopener-convert-html.exe\" \"%1\""
このとき、登録したパスの実行ファイルに対して、ファイルやフォルダのパスが引数として渡されるので、あとはこれを調理していきます。
4. いい感じのリンクをTeamsに貼りつけられるようにしよう
この方法でリンクを作るとして、http://localhost:10082/?path=C:\
くらいならまだ読めます。ですが、非ASCII文字が入ってきてURLエンコードされるとなるとさすがに達人じゃないと読めなくなってくるので、読みやすい表示にできないか考えます。
Teamsは少しだけHTMLに対応しているので、<a href="http://localhost:10082/?path=C:\" >C:\</a>
のようなHTMLを貼りつけるといい感じのリンクになってくれます。
というわけで、ファイルやフォルダのパスのリンクをいい感じのHTMLにしてクリップボードに登録するソフトを作ります。
どうすればHTMLをクリップボードに登録できるかというと、↓みたいな感じのUTF-8バイト列をクリップボードにセットします。Windowsって内部的にけっこうUTF-16だと思ってたんですが、ここはUTF-8なんですねー(UTF-16でもできるかは未確認)。
Version:0.9 StartHTML:000000 EndHTML:000000 StartFragment:000000 EndFragment:000000<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head> <body><!--StartFragment--> <a href="リンク先">リンクテキスト</a> <!--EndFragment--></body> </html>
というわけで、エクスプローラ上でShift+右クリックして「XOpener用にパスをコピー」すると
こんな感じにリンクとして貼り付けられるようになりました。
めでたしめでたし。