# 機能設計書 48-corehost

## 概要

本ドキュメントは、.NETランタイムにおけるcorehostコンポーネントの機能設計を記述したものである。corehostは、dotnet実行可能ファイル（muxer）として機能し、.NETアプリケーションの起動とランタイムのホスティングを担当するネイティブコンポーネントである。

### 本機能の処理概要

corehostは、`dotnet`コマンドのエントリーポイントとして動作し、ユーザーが指定した.NETアプリケーションを適切なランタイムでホストする責務を持つ。

**業務上の目的・背景**：.NETアプリケーションを実行するためには、適切なランタイム（CLR）を起動し、マネージドコードをロードして実行する必要がある。corehostは、この起動プロセスを管理し、フレームワーク依存型アプリケーション、自己完結型アプリケーション、シングルファイルアプリケーションなど、様々な配置形態をサポートする。

**機能の利用シーン**：
- `dotnet run`コマンドでアプリケーションを実行する時
- `dotnet myapp.dll`でアプリケーションを直接実行する時
- apphost（アプリケーションホスト）経由でアプリケーションを起動する時
- シングルファイルバンドルアプリケーションの実行時

**主要な処理内容**：
1. 実行可能ファイルのパス解決
2. apphostの場合、埋め込まれたDLL名の抽出
3. hostfxrの検索とロード
4. ランタイムの初期化とアプリケーションの起動
5. シングルファイルバンドルの検出と処理
6. エラーハンドリングとユーザーへのフィードバック

**関連システム・外部連携**：
- hostfxr（ランタイムフレームワークリゾルバー）
- CoreCLRランタイム
- OSのプロセス管理機能

**権限による制御**：特になし。ファイルシステムへのアクセス権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | コマンドライン | 主機能 | dotnetコマンドの実行 |

## 機能種別

ネイティブコンポーネント / ランタイムホスト

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| argc | int | Yes | コマンドライン引数の数 | - |
| argv | char_t*[] | Yes | コマンドライン引数配列 | - |

### 入力データソース

- コマンドライン引数
- 埋め込みDLL名（apphost）
- バンドルマーカー（シングルファイル）
- 環境変数（DOTNET_ROOT等）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| exit_code | int | アプリケーションの終了コード |

### 出力先

- 標準出力/標準エラー出力（エラーメッセージ）
- プロセス終了コード

## 処理フロー

### 処理シーケンス

```
1. トレース設定の初期化
   └─ trace::setup()

2. ホストパスの解決
   └─ pal::get_own_executable_path()
   └─ pal::fullpath()

3. apphostの場合
   └─ is_exe_enabled_for_execution()で埋め込みDLL名取得
   └─ アプリパスの構築

4. dotnetの場合
   └─ 引数からDLLパスを取得
   └─ セキュリティチェック（リネーム検出）

5. hostfxrのロード
   └─ hostfxr_resolver_tの初期化
   └─ fxr.status_code()でエラーチェック

6. アプリケーションの起動
   └─ シングルファイル: hostfxr_main_bundle_startupinfo
   └─ 通常: hostfxr_main_startupinfo
   └─ 旧バージョン互換: main_fn_v1

7. 終了処理
   └─ trace::flush()
   └─ エラーバッファリング処理（Windows）
```

### フローチャート

```mermaid
flowchart TD
    A[main] --> B[trace::setup]
    B --> C[exe_start]
    C --> D[get_own_executable_path]
    D --> E{FEATURE_APPHOST?}
    E -->|Yes| F[is_exe_enabled_for_execution]
    E -->|No| G[引数解析]
    F --> H{DLL名有効?}
    H -->|No| Z[エラー終了]
    H -->|Yes| I[アプリパス構築]
    G --> J{引数あり?}
    J -->|No| K[ヘルプ表示]
    J -->|Yes| I
    I --> L[hostfxr_resolver_t]
    L --> M{ロード成功?}
    M -->|No| Z
    M -->|Yes| N{バンドル?}
    N -->|Yes| O[hostfxr_main_bundle_startupinfo]
    N -->|No| P[hostfxr_main_startupinfo]
    O --> Q[終了処理]
    P --> Q
    Q --> R[exit_code返却]
    K --> R
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-48-01 | リネーム禁止 | dotnet.exeはリネームすると動作しない | FEATURE_APPHOST未定義時 |
| BR-48-02 | 埋め込みハッシュ検証 | apphostは有効なDLL名が埋め込まれている必要 | FEATURE_APPHOST時 |
| BR-48-03 | パス長制限 | 埋め込みDLL名は1024バイト以下 | apphost時 |
| BR-48-04 | シングルファイル優先 | バンドルマーカーがある場合はバンドルモード | bundle_marker_t::is_bundle()時 |

### 計算ロジック

埋め込みDLL名の検証:
```cpp
// SHA-256 of "foobar" をプレースホルダーとして使用
// ビルド時にdotnet buildがこれを実際のDLL名に置換
if (binding_len >= (hi_len + lo_len) &&
    compare_memory_nooptimization(&embed[0], hi_part, hi_len) &&
    compare_memory_nooptimization(&embed[hi_len], lo_part, lo_len)) {
    // プレースホルダーのままの場合はエラー
    return false;
}
```

## データベース操作仕様

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| CurrentHostFindFailure | ホストエラー | 自身のパスを解決できない | パスを確認 |
| AppHostExeNotBoundFailure | 設定エラー | apphostにDLL名が埋め込まれていない | dotnet buildで再ビルド |
| AppPathFindFailure | ファイルエラー | アプリケーションDLLが見つからない | パスを確認 |
| CoreHostEntryPointFailure | ホストエラー | dotnet.exeがリネームされている | 元の名前に戻す |
| FrameworkMissingFailure | 環境エラー | hostfxrが古い/見つからない | ランタイムを再インストール |
| InvalidArgFailure | 引数エラー | 引数なしでdotnet実行 | 引数を指定 |

### リトライ仕様

リトライは行わない。

## トランザクション仕様

該当なし

## パフォーマンス要件

- 起動オーバーヘッドを最小限に抑える
- シングルファイルバンドルの効率的な処理

## セキュリティ考慮事項

- dotnet.exeのリネーム検出（偽装防止）
- 埋め込みパスのバリデーション
- シンボリックリンクの解決

## 備考

- corehostは純粋なC++で実装され、ランタイムに依存しない
- Windows/Linux/macOSでクロスプラットフォーム対応
- FEATURE_APPHOSTマクロでapphost/dotnetの動作を分岐

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造とマクロを理解する

まず、コンパイル時の設定とプラットフォーム抽象化を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | corehost.cpp | `src/native/corehost/corehost.cpp` | 14-23行目のFEATUREマクロ |

**読解のコツ**:
- FEATURE_APPHOST: apphost（アプリケーションホスト）としてビルド
- FEATURE_LIBHOST: ライブラリホストとしてビルド
- CURHOST_TYPE: ホストタイプの文字列（"apphost" or "dotnet"）

#### Step 2: 埋め込みDLL名の処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | corehost.cpp | `src/native/corehost/corehost.cpp` | 39-41行目のEMBED_HASH定義、56-99行目のis_exe_enabled_for_execution() |

**主要処理フロー**:
- **58-64行目**: embedバッファからDLL名を取得
- **75-82行目**: パス長制限チェック
- **89-95行目**: プレースホルダーとの比較

#### Step 3: exe_startを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | corehost.cpp | `src/native/corehost/corehost.cpp` | 121-307行目のexe_start() |

**主要処理フロー**:
- **130-135行目**: 自身のパス解決
- **141-173行目**: FEATURE_APPHOST時のアプリパス構築
- **175-208行目**: dotnet時のセキュリティチェック
- **217-304行目**: hostfxrの呼び出し

#### Step 4: main関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | corehost.cpp | `src/native/corehost/corehost.cpp` | 309-345行目のmain()/wmain() |

### プログラム呼び出し階層図

```
main() / wmain()
    │
    ├─ trace::setup()
    │
    ├─ trace::info() [ログ出力]
    │
    ├─ apphost::buffer_errors() [Windows]
    │
    ├─ exe_start()
    │      │
    │      ├─ initialize_static_createdump() [静的ホスト]
    │      │
    │      ├─ pal::get_own_executable_path()
    │      │
    │      ├─ is_exe_enabled_for_execution() [apphost]
    │      │
    │      ├─ hostfxr_resolver_t()
    │      │
    │      ├─ fxr.resolve_main_bundle_startupinfo() [バンドル]
    │      │      └─ hostfxr_main_bundle_startupinfo()
    │      │
    │      └─ fxr.resolve_main_startupinfo() [通常]
    │             └─ hostfxr_main_startupinfo()
    │
    ├─ trace::flush()
    │
    └─ apphost::write_buffered_errors() [Windows]
```

### データフロー図

```
[入力]                    [処理]                           [出力]

argc, argv ─────▶ exe_start()
                        │
embed[] (apphost) ──▶   ├─ is_exe_enabled_for_execution()
                        │
環境変数 ───────────▶   ├─ hostfxr検索
                        │
                        ▼
                  hostfxr_main_*()
                        │
                        ▼
                  アプリケーション実行
                        │
                        ▼
                  exit_code
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| corehost.cpp | `src/native/corehost/corehost.cpp` | ソース | メインエントリポイント |
| hostfxr.h | `src/native/corehost/hostfxr.h` | ヘッダー | hostfxr API定義 |
| fxr_resolver.h | `src/native/corehost/fxr_resolver.h` | ヘッダー | hostfxrリゾルバー |
| error_codes.h | `src/native/corehost/error_codes.h` | ヘッダー | エラーコード定義 |
| pal.h | `src/native/corehost/pal.h` | ヘッダー | プラットフォーム抽象化 |
| trace.h | `src/native/corehost/trace.h` | ヘッダー | トレース/ログ機能 |
| bundle_marker.h | `src/native/corehost/bundle_marker.h` | ヘッダー | バンドルマーカー |
