2019年10月版 .NET Coreが動くまで 

## はじめに
下記のページは.NET Coreの起動プロセスについて日本語でまとめられた素晴らしい記事なのですが、現時点(2019/10/02)としてはちょっと古くなっています。
そこで私が.NET Coreのソースを呼んで気づいた部分についてこの記事に記載します。
完全に理解しているわけではないので間違いなどあればご指摘ください。

[.NET Coreが動くまで](http://yfakariya.blogspot.com/2017/03/net-core.html)

## ホスティングAPIについて

.NET Core 3.0以上であれば`nethost`および`hostfxr`ライブラリの使用が推奨されます。

[ネイティブ コードから .NET ランタイムを制御するカスタム .NET Core ホストを作成する](https://docs.microsoft.com/ja-jp/dotnet/core/tutorials/netcore-hosting#hosting-apis)

`nethost`は`hostfxr`のパスを取得するためだけのライブラリです。
だいたい以下の手順で`hostfxr`のパスを検索します。

```
1. 既にプロセスにhostfxrがロードされている場合はそこから取得
2. dotnetのルートパスを引数で渡した場合はそこからの相対パスで取得
3. アセンブリのパスを引数で渡した場合はそこから相対パスで取得
4. 環境変数からdotnetのルートパスを取得し、そこからの相対パスで取得
5. (Windowsの場合)レジストリからdotnetのルートパスを取得し、そこからの相対パスで取得
```

私の環境では`C:\Program Files\dotnet\host\fxr`に複数バージョンの`hostfxr`が存在しています。
複数バージョンの`hostfxr`が存在する場合、最新の`hostfxr`が選択されます。

## ホストモードについて

StandaloneモードはAppHostモードに変更されています。

https://github.com/dotnet/core-setup/blob/1def95819b537ec19aa89e774578bc66b0507609/src/corehost/cli/host_interface.h#L11-L24

```csharp
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モードにはならない気がします。
よくわかってないので詳しい方は教えていただけると助かります:bow:

## `dotnet run`について

`dotnet run`を実行するとMuxerモードで起動し`dotnet.dll`を実行する部分までは記事の通りです。

`dotnet run`で実行するプロジェクトの`UseAppHost`が有効になっている場合、`dotnet exec`コマンドは発行されません。
(Windowsの場合)代わりに`<アプリケーション名>.exe`がAppHostモードで起動します。

`UseAppHost`が無効の場合は記事の通りに`dotnet exec <アプリケーション>.dll`が実行されます。
すなわちMuxerモードで起動します。

AppHostモードで起動したかMuxerモードで起動したかはタスクマネージャを見れば簡単に判別することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42193/d12fff54-73de-3b9a-b6e6-ec0e13a60fd1.png)
(AppHostモードで起動した場合)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42193/c3c85bbf-5d36-b040-33e4-7304fed6ed32.png)
(Muxerモードで起動した場合)

AppHostモードで起動した場合は`.NET Core Host`と`dotnet-sample`というプロセスが立ち上がっているのがわかります。
Muxerモードで起動した場合は`.NET Core Host`が二つ立ち上がっているのが分かります。
一つ目は最初の`dotnet`コマンド、二つ目は`dotnet.dll`が起動した`dotnet`コマンドです。

```txt:Muxerモードdotnet.exeプロセス詳細
名前	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"	無効
```

## 最後に

挙動を調べるにあたって元記事はとても参考になりました。
今見ても十分勉強になることも多いです。
素敵な記事をありがとうございます:bow: