「Scoop + pwsh + Windows Terminal」にカスタムディレクトリ設定を混ぜたら詰まった話

こんにちは、くらめです。 初めてのブログでどんな風に書けばいいのかよくわかりませんが、気楽に書いていきたいと思います。

なお、以下はWindows Terminal v1.4.3141.0で起きたことを書いています。 別のバージョンをお使いの方は挙動が異なる可能性があるのでご了承ください。

背景

まずは今回起きた問題を一言で書いておきましょう。

Scoopのインストールディレクトリをデフォルトから変えたら、Windows TerminalのシェルのリストにPowerShell Coreが表示されなくなりました。

そもそもScoopとはなんぞやといいますと、Windows向けのとてもシンプルなパッケージマネージャーです。 PowerShellからコマンドを叩く形なので技術者よりのツールですが、 とても使いやすくて、アプリのインストールやアップデートをする手間が激減します。 Scoopの入門記事だったり解説記事だったりはQiitaなどにわかりやすい記事があるのでそちらを参照ください。

僕も1年ぐらい前からScoopに大変お世話になっているのですが、今日、悲劇が起きました。

「し、Cドライブが、赤くなってる……(Scoopのせいじゃない)」

はい、ただのアプリの入れすぎです。別にScoopに問題があるわけではないです。 Scoopはデフォルトでは

$env:USERPROFILE\scoop

というディレクトリをインストール時に作成し、そのディレクトリ下にアプリをじゃんじゃんインストールしていきます。 当然、このディレクトリはCドライブ下にあり、CドライブにはSSDを使うことが多い昨今、容量が危なくなりやすいわけです。

もちろん解決策はあります。 Scoopはアプリをインストールするディレクトリをインストール時に指定することができますので、ScoopをインストールするディレクトリをHDDドライブなどに変更すれば問題はなくなります。 インストールディレクトリの変更方法についてはScoopのWikiの通りにやればOKです。 もうScoopの運用をしちゃってるんだが? という方は「scoopのインストール先を変更する」という記事が参考になりますので、見てみてください。

そして、無事、Scoopの移行が終わったところで第二の悲劇が起こりました。

f:id:kurame-yotsuba:20201114020958p:plain

そう、Windows Terminalがエラーになっているのです。 ちなみにWindows TerminalはScoopで入れているわけではないので、インストールがミスってるということはありません。 そして、後ろのタブに表示されているアイコンをご覧ください。 そうです。こいつ、PowerShell Coreじゃありません。

キサマ! 旧世代の遺物、「Windows PowerShell」!!

問題

今回ぶち当たった問題は以下です。

Scoopでインストールディレクトリをデフォルトから変更すると、Windows TerminalがPowerShell Coreを読み込もうとしたときにエラーになる。

原因

PowerShell Coreのインストールをミスったのかなとか、Windows Terminalを再インストールしたら直るかなとか、PowerShell Coreをグローバルインストールに変えたらどうだろうとか色々試していくうちにひとつ、Windows TerminalでPowerShell Coreを開けたことがありました。 それは%USERPROFILE%\scoopディレクトリにPowerShell Coreをインストールすると上手く動いたのです!

……いや、まあそうでしょうね。今までそれで動いていましたもんね。

で、そもそもWindows TerminalはどうやってPowerShell Coreを見つけ出しているのだろうとsettings.jsonを見てみれば

"source": "Windows.Terminal.PowershellCore"

という指定はあるも、それでどうやって探しているのかはわからず。

Microsoft Docsにも

LinuxWindows サブシステム (WSL) と PowerShell のシェルがマシンにインストールされている場合、これらに対するプロファイルが自動的に作成されます。 これにより、実行可能ファイルを探す必要なしに、すべてのシェルをターミナルに簡単に含めることができるようになります。 これらのプロファイルは、source プロパティを使用して生成されます。このプロパティでは、適切な実行可能ファイルを見つける場所がターミナルに通知されます。

とあるも、その「適切な実行可能ファイルを見つける場所」とやらはわからず……。

Windows Terminalは幸いGitHubに公開されていますので、ソースコードを見ればなんとかなるかなぁと覗いて見たらなんかそれっぽい箇所を見つけ――

_accumulatePwshExeInDirectory(L"%USERPROFILE%\\scoop\\shims", PowerShellFlags::Scoop, versions);

ってハードコーディングかよ!

そりゃディレクトリ変更したら見つからないわけだよ。 つまり、ディレクトリを変更してエラーになった原因は、ディレクトリを変更したことだったんだね!

まあ、そもそもScoopを特別扱いしてくれている(他だとdotnet CLI)時点でMicrosoft優しいという気持ちも溢れてきますが……えぇー(困惑)。

解決策

なにはともあれ、原因がわかってしまえばほぼ終わりです。 %USERPROFILE%\scoopにScoopのインストールディレクトリがなくてはいけないので、今回指定したカスタムディレクトリへのシンボリックリンクなりジャンクションなりを貼ってやれば、それでとりあえずのところ問題はありません。

ただし、シンボリックリンクですと管理者権限 or 開発者モードが必要になってくるので、ジャンクションの方がいいかもしれません。

//カレントディレクトリが$env:USERPROFILEだとする
New-Item -ItemType Junction -Value カスタムディレクトリのパス -Name scoop

って感じでやればOKです。

対処療法的な感じになってしまいましたが、これで僕のCドライブもまだまだ安心して使えそうです。

参考