# 通知設計書 23-ApplicationStart

## 概要

本ドキュメントは、Windows Terminalのコンソールホスト（conhost）におけるApplicationStartアクセシビリティ通知の設計を記述する。コンソールにアプリケーションが接続（アタッチ）された際に、MSAA経由でEVENT_CONSOLE_START_APPLICATIONイベントを支援技術に通知する仕組みである。

### 本通知の処理概要

ApplicationStart通知は、新しいアプリケーションプロセスがコンソールに接続された際に、そのプロセスIDをEVENT_CONSOLE_START_APPLICATIONイベントとして支援技術に送信するアクセシビリティ通知である。

**業務上の目的・背景**：スクリーンリーダー等の支援技術は、どのアプリケーションがコンソールを使用しているかを把握する必要がある。新しいプロセスがコンソールに接続された際にその情報を通知することで、支援技術はプロセスごとに適切な読み上げ動作やフィルタリングを行うことができる。

**通知の送信タイミング**：コンソールへの新規プロセス接続時に送信される。具体的には、ウィンドウIO初期化時（windowio.cpp内でAccessibilityNotifierの初期化と同時）およびIoDispatchers::ConsoleHandleConnectionRoutine内（プロセスのコンソールアタッチ処理時）の2箇所から呼び出される。

**通知の受信者**：WinEventフックを通じてEVENT_CONSOLE_START_APPLICATIONを購読している支援技術プロセス。

**通知内容の概要**：接続されたプロセスのプロセスID（PID）がイベントパラメータとして送信される。

**期待されるアクション**：支援技術はアプリケーション開始を認識し、必要に応じてアプリケーション固有の設定や動作を適用する。

## 通知種別

アクセシビリティ通知（MSAA WinEvent: EVENT_CONSOLE_START_APPLICATION）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（デバウンスなし、即座に発行） |
| 優先度 | 中 |
| リトライ | 無 |

### 送信先決定ロジック

MSAAが有効（_msaaEnabled が true）の場合に無条件で通知を発行する。IsWinEventHookInstalledのチェックは行わない。IConsoleControl::NotifyWinEventを介してOS側でフック購読者に配信される。

## 通知テンプレート

### WinEventパラメータ

| 項目 | 内容 |
|-----|------|
| イベントID | EVENT_CONSOLE_START_APPLICATION |
| HWND | コンソールウィンドウハンドル（_hwnd） |
| idObject (LONG) | プロセスID（pid） |
| idChild (LONG) | 0 |

### 本文テンプレート

```
IConsoleControl::NotifyWinEvent(EVENT_CONSOLE_START_APPLICATION, _hwnd, pid, 0)
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| pid | 接続されたプロセスのプロセスID | ProcessData->dwProcessId | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 内部処理 | ウィンドウIO初期化（windowio.cpp） | MSAAが有効 | コンソールの初期化時に最初のプロセスが接続される際 |
| 内部処理 | ConsoleHandleConnectionRoutine（IoDispatchers.cpp） | MSAAが有効 | プロセスがコンソールにアタッチする際 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| MSAAが無効 | _msaaEnabled が false の場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[プロセスがコンソールに接続] --> B{発生元}
    B -->|初期化時| C[windowio.cpp: 初期化処理]
    B -->|アタッチ時| D[IoDispatchers::ConsoleHandleConnectionRoutine]
    C --> E[AccessibilityNotifier::ApplicationStart呼び出し]
    D --> E
    E --> F{MSAAが有効?}
    F -->|Yes| G[IConsoleControl::NotifyWinEvent発行]
    F -->|No| H[スキップ]
    G --> I[EVENT_CONSOLE_START_APPLICATION送信]
    I --> J[終了]
    H --> J
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| NotifyWinEvent失敗 | OSレベルの障害 | IConsoleControlの戻り値に依存するが、呼び出し元では無視される |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0 |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A |

## 配信設定

### レート制限

該当なし（プロセス接続ごとに1回だけ発行）

### 配信時間帯

制限なし

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

- プロセスIDのみを送信するため、機密情報漏洩のリスクは低い
- WinEvent機構のセキュリティモデルに準拠

## 備考

- ApplicationStartはconst関数であり、State構造体を変更しない。他のアクセシビリティ通知と異なり、デバウンスされず即座に同期的に発行される
- IsWinEventHookInstalledのチェックを行わない点で他の通知（ScrollViewport、Layout等）と異なる
- WindowIO初期化時にはAccessibilityNotifier::Initializeも同時に呼び出される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AccessibilityNotifier.h | `src/host/AccessibilityNotifier.h` | ApplicationStart関数のシグネチャ（行34）。constメンバ関数であり、DWORD pidを引数に取る |

**読解のコツ**: ApplicationStartはconst関数であるため、State構造体を操作しない。デバウンスの仕組みは使用されず、直接IConsoleControlを呼び出す。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | windowio.cpp | `src/interactivity/win32/windowio.cpp` | AccessibilityNotifier初期化後のApplicationStart呼び出し（行901-902） |
| 2-2 | IoDispatchers.cpp | `src/server/IoDispatchers.cpp` | ConsoleHandleConnectionRoutine内のApplicationStart呼び出し（行462-463） |

**主要処理フロー**:
1. **windowio.cpp 行900-902**: `an.Initialize()` の直後に `an.ApplicationStart(ProcessData->dwProcessId)` が呼び出される
2. **IoDispatchers.cpp 行462-463**: プロセスのアタッチ時に `an.ApplicationStart(dwProcessId)` が呼び出される

#### Step 3: ApplicationStart関数の実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AccessibilityNotifier.cpp | `src/host/AccessibilityNotifier.cpp` | ApplicationStart関数（行306-312） |

**主要処理フロー**:
- **行308**: `_msaaEnabled` の条件チェック
- **行310-311**: `ServiceLocator::LocateConsoleControl()` でIConsoleControlを取得し、`NotifyWinEvent` を呼び出す

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

```
windowio.cpp: 初期化処理 (行902)
    |
    +-- AccessibilityNotifier::ApplicationStart(pid)
           |
           +-- IConsoleControl::NotifyWinEvent(EVENT_CONSOLE_START_APPLICATION, hwnd, pid, 0)

IoDispatchers::ConsoleHandleConnectionRoutine (IoDispatchers.cpp:463)
    |
    +-- AccessibilityNotifier::ApplicationStart(pid)
           |
           +-- IConsoleControl::NotifyWinEvent(EVENT_CONSOLE_START_APPLICATION, hwnd, pid, 0)
```

### データフロー図

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

プロセスID               AccessibilityNotifier              WinEvent
(ProcessData->          ::ApplicationStart(pid)      -->    EVENT_CONSOLE_START_APPLICATION
 dwProcessId)    -----> IConsoleControl                      (pid パラメータ)
                        ::NotifyWinEvent()                      |
                                                                v
                                                         支援技術（NVDA等）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AccessibilityNotifier.h | `src/host/AccessibilityNotifier.h` | ソース（ヘッダ） | ApplicationStart関数宣言 |
| AccessibilityNotifier.cpp | `src/host/AccessibilityNotifier.cpp` | ソース（実装） | ApplicationStart実装 |
| windowio.cpp | `src/interactivity/win32/windowio.cpp` | ソース（実装） | 初期化時の呼び出し元 |
| IoDispatchers.cpp | `src/server/IoDispatchers.cpp` | ソース（実装） | プロセスアタッチ時の呼び出し元 |
| globals.h | `src/host/globals.h` | ソース（ヘッダ） | グローバルaccessibilityNotifierインスタンス |
