アンセケターメンはてなエディション

いつどこで誰に見られても恥ずかしいコードが置かれています

.NET 8で追加されたであろうAPIを知りたかった話

.NET 8で追加されたであろうAPIを知りたかったので調べた。

最初はMicrosoft Learnをスクレイピングするかと思ったのだが、よくよく考えてみれば普通にGitHubリポジトリdotnet/dotnet-api-docs)に上がってたのでこっちを解析することにした。

使用したコードを置いておく。酩酊状態でtypoしまくりながら30分くらいかけて書いた。

github.com

続きを読む

TeamsやDiscordでエクスプローラを起動してフォルダを開く

下書きで一年以上放置しちゃってた。

前回は、ChromeやEdgeで共有フォルダをエクスプローラで開いたり、xlsxをExcelで直接開いたりできるツールを作りました。

anseketamen.hatenablog.com

この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);

XOpener/xopener/helpers/xopener-trans.cs at 35f9bd129a1d7200766287464d5c9d5e69c423a3 · anseketamen/XOpener · GitHub

3. いい感じのリンクを自動生成できるようにしよう

レジストリをいじくって、エクスプローラーでShift+右クリックすると「XOpener用にパスをコピー」というメニューが出るようにしましょう。

XOpener/xopener/xopener-full.reg at 35f9bd129a1d7200766287464d5c9d5e69c423a3 · anseketamen/XOpener · GitHub

↓みたいな感じのやつを、「ファイル選択時」「フォルダ選択時」「フォルダの何もないとこ選択時」「ドライブ選択時」の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用にパスをコピー」すると

こんな感じにリンクとして貼り付けられるようになりました。

めでたしめでたし。

Kotlinでもnameof演算子を使いたい!

C#にはnameof演算子というものがあり、変数名を文字列リテラルにして埋め込んでくれる(主にデバッグとINotifyPropertyChanged向けの)便利機能があります。

Kotlinにはないらしいので頑張ってそれっぽいのを錬成(海外フォーラム丸パクリともいう)してみました。

続きを読む

Markdown PDFでPDF変換されない問題を解決する

めちゃくちゃ便利な VSCode拡張機能 Markdown PDF ですが、特殊な環境(変なグループポリシーが設定されていたりプロキシがあったり)だとうまく動かないことがありました。動くように試行錯誤した結果を残しておきます。

続きを読む

ChromeやEdgeでエクスプローラを起動してフォルダを開く

2022年6月にInternet ExplorerIE)が終了しました。

社内のSMB共有ファイルサーバにファイルやフォルダがあって、IEでリンク集みたいなHTMLファイルからアクセスする運用をしていないでしょうか。
後継であるEdgeやChromeでは、IEと違ってリンクからファイルを直接開いたり、エクスプローラを起動させたりできなくなりました。なんということ!!
一応file:プロトコルでアクセスはできますが、フォルダはよくわからんリストになるし、ファイルを開こうとすると一旦ダウンロードという形になるんですよね。 xlsxをExcelで直接開けない!IEだと開けたのに!みたいな。

そんなときのために、IEと(ほぼ)同じ感じでファイルやフォルダにアクセスするための手段を作りました。
セキュリティ厳しめのところでもできるように、Windowsにもともと入っている機能だけで作っていきます。

成果物はGitHubに上げてあります。仕組みを知りたいよって人は続きへどうぞ。

github.com

続きを読む

C#erのKotlin/Android入門記 #3 クラス

入門記3回目。クラス周りについて。

なんか.NET MAUIがRC公開を重ねてるけど非Preview版のVisual StudioでGAするのは22年後半らしいのでまだセーフ。あれ君22Q2にリリースって言ってなかったっけ?

続きを読む