dotnetコマンド(.NET CLI)のinfo, list-sdks, list-runtimes はどこから出力されているのか
dotnetコマンドにはSDKやランタイムの情報を表示するオプションがある。
この処理を調べていて、気になったことがあったのでメモ。
C:\WINDOWS\system32>dotnet --list-sdks
5.0.103 [C:\Program Files\dotnet\sdk]
6.0.202 [C:\Program Files\dotnet\sdk]
8.0.101 [C:\Program Files\dotnet\sdk]
.NET CLIは以下のリポジトリで開発されている。
とりあえず、src/Cli/dotnet
のプロジェクトに引数--info
を渡してデバッグしてみる。
~省略~
インストール済みの .NET ワークロード:
表示するインストール済みワークロードはありません。
そうすると、出力がインストール済みの .NET ワークロード
で終了してしまう。
イントール済みのdotnetコマンドではインストール済みの .NET ワークロード
の後にHost
と続くが、デバッグ中はなぜか出力されない。
~省略~
インストール済みの .NET ワークロード:
Workload version: 8.0.100-manifests.30fce108
表示するインストール済みワークロードはありません。
Host:
Version: 8.0.1
Architecture: x64
Commit: bf5e279d92
~省略~
--list-sdks
、--list-runtimes
に関しては出力されないどころか、help
コマンドのような結果が出力される。
パースされたり色々処理が挟まっている部分は割愛。
--info
オプション自体の処理はここで行われる。
PrintInfo()
関数を見たら分かる通り、--info
オプションの処理はインストール済みの .NET ワークロード
を出力するPrintWorkloadsInfo()
関数で終わっている。
また、--list-sdks
、--list-runtimes
は処理する場所自体存在しない。
では、どこから出力されているかというと、答えはhostfxr
モジュール。
hostfxr
についてはここに詳しく書かれている。(いい記事なので読もう!)
hostfxr
はホストモードがmuxer
(dotnetコマンドで起動された場合のモード)の時、ネイティブでオプションを処理する。
デバッグ時に--info
や--list-sdks
、--list-runtimes
が通常と異なる動作をしたのはmuxer
モードで起動されていなかったから。
--info
の処理。マネージド(dotnet.dll)を実行した後に追加でinfo情報を出力している。(command_line::print_muxer_info
)
--list-sdks
、--list-runtimes
の処理。
こちらはマネージド自体実行しない。
dotnet helpで以下のように表記されてるのは内部で処理が分かれているから。
使用法: dotnet [runtime-options] [path-to-application] [arguments]
使用法: dotnet [sdk-options] [command] [command-options] [arguments]
言われてみれば納得。