# 機能設計書 85-動的プロファイル生成(WSL)

## 概要

本ドキュメントは、Windows Terminal がインストール済みの WSL（Windows Subsystem for Linux）ディストリビューションを自動検出し、対応するプロファイルを動的に生成する機能を記述する。

### 本機能の処理概要

**業務上の目的・背景**：ユーザーが WSL ディストリビューションをインストールした際に、手動で settings.json にプロファイルを追加する手間を省く。Windows Terminal が自動的に利用可能な WSL ディストリビューションを検出し、対応するプロファイルを生成することで、即座に利用可能にする。

**機能の利用シーン**：Windows Terminal の起動時に自動的に実行される。Ubuntu、Debian、Alpine などの WSL ディストリビューションがインストールされると、次回起動時に新しいプロファイルが自動的に追加される。

**主要な処理内容**：
1. Windows レジストリ（HKCU\Software\Microsoft\Windows\CurrentVersion\Lxss）から WSL ディストリビューション情報を取得
2. 各ディストリビューションの GUID とディストリビューション名を列挙
3. Docker / Rancher のユーティリティディストリビューションをフィルタリング
4. "Modern" フラグが設定されたディストリビューション（WSL2専用）をスキップ
5. 各ディストリビューションに対してプロファイルを生成（コマンドライン、アイコン、開始ディレクトリ等）

**関連システム・外部連携**：Windows レジストリ（Lxss キー）、wsl.exe（System32 ディレクトリ）。

**権限による制御**：HKEY_CURRENT_USER の読み取り権限が必要（通常ユーザーで可能）。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | バックグラウンド処理。直接の関連画面はない |

## 機能種別

データ連携 / 自動検出

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| profiles | std::vector<winrt::com_ptr<Profile>>& | Yes | 生成されたプロファイルを格納するベクタ（参照渡し） | - |

### 入力データソース

- Windows レジストリ：`HKCU\Software\Microsoft\Windows\CurrentVersion\Lxss` 配下のサブキー
- 各サブキーの `DistributionName` 値と `Modern` 値

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Profile | winrt::com_ptr<Profile> | 各 WSL ディストリビューション用のプロファイルオブジェクト |

### 出力先

- profiles ベクタに追加され、SettingsLoader の inboxSettings.profiles に統合される

## 処理フロー

### 処理シーケンス

```
1. WslDistroGenerator::GenerateProfiles() が呼び出される
   └─ openWslRegKey() で Lxss レジストリキーを開く
2. getWslGuids() で全ディストリビューションの GUID を列挙
   └─ RegEnumKeyEx で {GUID} 形式のサブキーを列挙
3. getWslNames() で各 GUID からディストリビューション名を取得
   └─ RegQueryValueExW で DistributionName を読み取り
   └─ Modern フラグが 1 のディストリビューションはスキップ
4. namesToProfiles() でプロファイルを生成
   └─ Docker / Rancher プレフィックスのディストリビューションをスキップ
   └─ makeProfile() で各ディストリビューションのプロファイルを作成
5. makeProfile() でプロファイルの詳細を設定
   └─ コマンドライン: C:\Windows\System32\wsl.exe -d {distName}
   └─ カラースキーム: Campbell
   └─ 開始ディレクトリ: ~ (Build 19041+)
   └─ アイコン: ms-appx:///ProfileIcons/{guid}.png
   └─ パス変換スタイル: WSL
```

### フローチャート

```mermaid
flowchart TD
    A[GenerateProfiles 開始] --> B[openWslRegKey でレジストリオープン]
    B --> C{成功?}
    C -->|No| D[終了 - プロファイルなし]
    C -->|Yes| E[getWslGuids で GUID 列挙]
    E --> F{成功?}
    F -->|No| D
    F -->|Yes| G[getWslNames でディストリビューション名取得]
    G --> H[namesToProfiles でプロファイル生成]
    H --> I{各ディストリビューション}
    I --> J{Docker/Rancher?}
    J -->|Yes| K[スキップ]
    J -->|No| L[makeProfile でプロファイル作成]
    L --> I
    K --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-85-01 | Docker除外 | docker-desktop プレフィックスのディストリビューションは除外 | プロファイル生成時 |
| BR-85-02 | Rancher除外 | rancher-desktop プレフィックスのディストリビューションは除外 | プロファイル生成時 |
| BR-85-03 | Modern除外 | Modern=1 のディストリビューション（WSL2専用内部ディストリ）は除外 | ディストリビューション名取得時 |
| BR-85-04 | WSLパス変換 | Build 19041以上では wsl.exe --cd がLinuxパスに対応。開始ディレクトリを ~ に設定 | OSビルド19041以上 |
| BR-85-05 | セキュアパス | wsl.exe は必ず C:\Windows\System32 から起動（パスハイジャック防止） | 常時 |

### 計算ロジック

該当なし。

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

該当なし（レジストリアクセスのみ）。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ERROR_SUCCESS以外 | レジストリアクセス失敗 | Lxss キーが存在しない場合 | 空のプロファイルリストを返す |
| - | ディストリビューション名取得失敗 | サブキーの読み取りに失敗 | そのディストリビューションをスキップ |

### リトライ仕様

リトライは行わない。次回アプリ起動時に再度検出される。

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

該当なし。

## パフォーマンス要件

レジストリアクセスのみのため高速に完了する。

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

- wsl.exe は GetSystemDirectoryW で取得した System32 パスから明示的に起動し、パスハイジャックを防止（GH#11096）。

## 備考

- 名前空間：`Windows.Terminal.Wsl`
- レガシー GUID 例：Debian (58ad8b0c-...), Ubuntu (2c4de342-...), Alpine (1777cdf0-...)
- ジェネレータアイコン：`ms-appx:///ProfileGeneratorIcons/WSL.png`

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | IDynamicProfileGenerator.h | `src/cascadia/TerminalSettingsModel/IDynamicProfileGenerator.h` | 動的プロファイルジェネレータの基底インターフェース（28-36行目）。GetNamespace / GenerateProfiles の契約を確認 |

**読解のコツ**: IDynamicProfileGenerator は純粋仮想クラスで、全てのジェネレータがこのインターフェースを実装する。namespace がプロファイルの一意性識別に使用される。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | WslDistroGenerator.h | `src/cascadia/TerminalSettingsModel/WslDistroGenerator.h` | WslDistroGenerator クラス定義（23-30行目） |
| 2-2 | WslDistroGenerator.cpp | `src/cascadia/TerminalSettingsModel/WslDistroGenerator.cpp` | GenerateProfiles メソッド（241-257行目）がエントリーポイント |

**主要処理フロー**:
1. **241-257行目**: GenerateProfiles() - レジストリキーオープン → GUID列挙 → 名前取得 → プロファイル生成
2. **62-83行目**: makeProfile() - コマンドライン・アイコン・開始ディレクトリの設定
3. **92-105行目**: namesToProfiles() - Docker/Rancher フィルタリング

#### Step 3: レジストリアクセスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | WslDistroGenerator.cpp | `src/cascadia/TerminalSettingsModel/WslDistroGenerator.cpp` | openWslRegKey（113-121行目）、getWslGuids（149-177行目）、getWslNames（189-229行目） |

**主要処理フロー**:
- **113-121行目**: openWslRegKey - HKCU\Software\Microsoft\Windows\CurrentVersion\Lxss を開く
- **149-177行目**: getWslGuids - RegEnumKeyEx で {GUID} サブキーを列挙
- **189-229行目**: getWslNames - 各 GUID の DistributionName を取得。Modern=1 はスキップ

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

```
SettingsLoader::GenerateProfiles (CascadiaSettingsSerialization.cpp:208)
    │
    └─ WslDistroGenerator::GenerateProfiles (WslDistroGenerator.cpp:241)
           │
           ├─ openWslRegKey() (WslDistroGenerator.cpp:113)
           │
           ├─ getWslGuids() (WslDistroGenerator.cpp:149)
           │
           ├─ getWslNames() (WslDistroGenerator.cpp:189)
           │      └─ openDistroKey() (WslDistroGenerator.cpp:130)
           │
           └─ namesToProfiles() (WslDistroGenerator.cpp:92)
                  └─ makeProfile() (WslDistroGenerator.cpp:62)
                         └─ CreateDynamicProfile() (DynamicProfileUtils.h)
```

### データフロー図

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

Windowsレジストリ ───▶ openWslRegKey ──▶ getWslGuids ──▶ getWslNames
(HKCU\...\Lxss)                                              │
                                                              ▼
                                                     namesToProfiles
                                                     (Docker/Rancher除外)
                                                              │
                                                              ▼
                                                        makeProfile
                                                              │
                                                              ▼
                                                  Profile オブジェクト群
                                                  (profiles ベクタに追加)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| WslDistroGenerator.h | `src/cascadia/TerminalSettingsModel/WslDistroGenerator.h` | ヘッダ | WslDistroGenerator クラス定義 |
| WslDistroGenerator.cpp | `src/cascadia/TerminalSettingsModel/WslDistroGenerator.cpp` | ソース | WSL ディストリビューション検出とプロファイル生成の実装 |
| IDynamicProfileGenerator.h | `src/cascadia/TerminalSettingsModel/IDynamicProfileGenerator.h` | ヘッダ | 動的プロファイルジェネレータインターフェース |
| DynamicProfileUtils.h | `src/cascadia/TerminalSettingsModel/DynamicProfileUtils.h` | ヘッダ | CreateDynamicProfile ユーティリティ |
| LegacyProfileGeneratorNamespaces.h | `src/cascadia/TerminalSettingsModel/LegacyProfileGeneratorNamespaces.h` | ヘッダ | 名前空間定数 |
| CascadiaSettingsSerialization.cpp | `src/cascadia/TerminalSettingsModel/CascadiaSettingsSerialization.cpp` | ソース | GenerateProfiles / _executeGenerator からの呼び出し元 |
