はじめに
下記のページは.NET Coreの起動プロセスについて日本語でまとめられた素晴らしい記事なのですが、現時点(2019/10/02)としてはちょっと古くなっています。
そこで私が.NET Coreのソースを呼んで気づいた部分についてこの記事に記載します。
完全に理解しているわけではないので間違いなどあればご指摘ください。
ホスティングAPIについて
.NET Core 3.0以上であればnethost
およびhostfxr
ライブラリの使用が推奨されます。
ネイティブ コードから .NET ランタイムを制御するカスタム .NET Core ホストを作成する
nethost
はhostfxr
のパスを取得するためだけのライブラリです。
だいたい以下の手順でhostfxr
のパスを検索します。
1. 既にプロセスにhostfxrがロードされている場合はそこから取得
2. dotnetのルートパスを引数で渡した場合はそこからの相対パスで取得
3. アセンブリのパスを引数で渡した場合はそこから相対パスで取得
4. 環境変数からdotnetのルートパスを取得し、そこからの相対パスで取得
5. (Windowsの場合)レジストリからdotnetのルートパスを取得し、そこからの相対パスで取得
私の環境ではC:\Program Files\dotnet\host\fxr
に複数バージョンのhostfxr
が存在しています。
複数バージョンのhostfxr
が存在する場合、最新のhostfxr
が選択されます。
ホストモードについて
StandaloneモードはAppHostモードに変更されています。
enum host_mode_t
{
invalid = 0,
muxer, // Invoked as "dotnet.exe".
apphost, // Invoked as <appname>.exe from the application base; this is the renamed "apphost.exe".
split_fx, // Invoked as "corehost.exe" for xunit scenarios. Supported for backwards compat for 1.x apps.
// Split FX means, the host is operating like "corerun.exe" in a split location from the application base (CORE_ROOT equivalent),
// but it has its "hostfxr.dll" next to it.
libhost, // Invoked from a non-exe scenario (e.g. COM Activation or self-hosting native application)
};
分離FXモードについて
記事では分離FXモードについて以下の記載があります。
つまり、dotnet app.dll を実行すると、以下のように動作します。
dotnet.exe という名前の corehost.exe が、分離 FX モードで app.dll を実行します。
dotnet.exe はホスティング API を使用して、app.dll に定義されたエントリポイントを呼び出します。
しかし、実際に実行するとMuxerモードで実行されます。
同記事の上部に
そうではなく、同じディレクトリに coreclr.dll(または libcoreclr.so か libcoreclr.dylib)がある場合、「分離 FX モード」になります。
とあるので元々分離FXモードにはならない気がします。
よくわかってないので詳しい方は教えていただけると助かります
dotnet run
について
dotnet run
を実行するとMuxerモードで起動しdotnet.dll
を実行する部分までは記事の通りです。
dotnet run
で実行するプロジェクトのUseAppHost
が有効になっている場合、dotnet exec
コマンドは発行されません。
(Windowsの場合)代わりに<アプリケーション名>.exe
がAppHostモードで起動します。
UseAppHost
が無効の場合は記事の通りにdotnet exec <アプリケーション>.dll
が実行されます。
すなわちMuxerモードで起動します。
AppHostモードで起動したかMuxerモードで起動したかはタスクマネージャを見れば簡単に判別することができます。
AppHostモードで起動した場合は.NET Core Host
とdotnet-sample
というプロセスが立ち上がっているのがわかります。
Muxerモードで起動した場合は.NET Core Host
が二つ立ち上がっているのが分かります。
一つ目は最初のdotnet
コマンド、二つ目はdotnet.dll
が起動したdotnet
コマンドです。
名前 PID 状態 ユーザー名 CPU メモリ (アクティブなプライベート ワーキング セット) コマンド ライン UAC の仮想化
dotnet.exe 12980 実行中 xxx 00 33,048 K dotnet run 無効
dotnet.exe 11200 実行中 xxx 00 3,944 K "dotnet" exec "C:\Users\xxx\Documents\dotnet-sample\bin\Debug\netcoreapp3.0\dotnet-sample.dll" 無効
最後に
挙動を調べるにあたって元記事はとても参考になりました。
今見ても十分勉強になることも多いです。
素敵な記事をありがとうございます