# 通知設計書 69-AviSynth未検出エラー

## 概要

本ドキュメントは、StaxRipアプリケーションにおける「AviSynth未検出エラー」通知の設計仕様を定義する。システムにインストールされたAviSynthが検出できない場合に、ユーザーにエラーを通知し、ポータブルモードへの自動切り替えを報告するための通知である。

### 本通知の処理概要

本通知は、AviSynthスクリプトを使用する設定でアプリケーションが動作している際に、システムにインストールされたAviSynthが見つからない場合に表示されるエラー通知である。ユーザーに問題を通知すると共に、ポータブルモードへの自動フォールバックが行われたことを報告する。

**業務上の目的・背景**：StaxRipは動画スクリプティングエンジンとしてAviSynthをサポートしている。AviSynthはシステムにインストールする方式と、StaxRip同梱のポータブル版を使用する方式がある。ユーザーがインストール版を使用する設定にしているが、実際にはインストールされていない場合に、処理の失敗を防ぐためにポータブルモードへ自動的にフォールバックし、その旨をユーザーに通知する。

**通知の送信タイミング**：MainFormのOnActivatedイベントハンドラ内で、FrameServerHelp.IsAviSynthPortableがFalse（インストール版を使用する設定）かつ、FrameServerHelp.GetAviSynthInstallPath()が空文字列を返した（インストールパスが見つからない）場合に表示される。

**通知の受信者**：現在操作中のユーザー（アプリケーションの操作者）に対してモーダルダイアログとして直接表示される。

**通知内容の概要**：AviSynthのインストールが見つからなかったこと、および代替としてポータブルモードを使用することを伝えるメッセージが表示される。

**期待されるアクション**：ユーザーは通知を確認し、そのままポータブルモードで使用するか、または正式にAviSynthをシステムにインストールして再起動する。

## 通知種別

アプリ内通知（モーダルダイアログ / TaskDialog）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（ユーザー操作をブロック） |
| 優先度 | 高 |
| リトライ | 無し |

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

本通知はUIスレッド上でモーダルダイアログとして表示されるため、送信先決定ロジックは存在しない。操作中のユーザーに直接表示される。

## 通知テンプレート

### ダイアログ通知の場合

| 項目 | 内容 |
|-----|------|
| ダイアログタイプ | TaskDialog |
| アイコン | Error（エラーアイコン） |
| タイトル | AviSynth installation not found, using portable mode instead. |
| ボタン | OK |
| コピーボタン | あり |

### 本文テンプレート

```
AviSynth installation not found,
using portable mode instead.
```

注：メッセージ内にBR（改行）が含まれる

### 添付ファイル

なし

## テンプレート変数

本通知にはテンプレート変数は使用されない。

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| N/A | N/A | N/A | N/A |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| アプリケーション起動 | MainForm.OnActivatedイベント | FrameServerHelp.IsAviSynthPortable = False AND FrameServerHelp.GetAviSynthInstallPath() = "" | インストール版を使用する設定だが、インストールパスが見つからない場合 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| ポータブルモードが設定されている場合 | FrameServerHelp.IsAviSynthPortableがTrueの場合 |
| インストールパスが見つかった場合 | GetAviSynthInstallPath()が有効なパスを返した場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[MainForm.OnActivated イベント] --> B[UpdateNextButton呼び出し]
    B --> C{FrameServerHelp.IsAviSynthPortable?}
    C -->|True| D[AviSynthチェックスキップ]
    C -->|False| E[FrameServerHelp.GetAviSynthInstallPath呼び出し]
    E --> F{インストールパスが空?}
    F -->|No| D
    F -->|Yes| G[MsgError表示]
    G --> H[s.AviSynthMode = FrameServerMode.Portable に設定]
    H --> D
    D --> I[VapourSynthチェックへ続く]
```

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

### 参照テーブル一覧

本通知はデータベースを使用しない。レジストリとファイルシステムを参照する。

| データソース | 用途 | 備考 |
|-----------|------|------|
| Registry.ClassesRoot | AviSynthのCOMクラス登録確認 | CLSID\{E6D6B700-124D-11D4-86F3-DB80AFD98778} |
| Folder.System | AviSynth.dllの存在確認 | %SystemRoot%\System32 |
| s.AviSynthMode | 現在のモード設定 | FrameServerMode列挙型 |

### 更新対象

| 対象 | 操作 | 概要 |
|-----------|------|------|
| s.AviSynthMode | 上書き | FrameServerMode.Portableに変更 |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| AviSynthインストール未検出 | レジストリおよびファイルシステムでAviSynthが見つからない | MsgError表示後、ポータブルモードに自動切替 |

### リトライ仕様

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

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | なし |
| 1日あたり上限 | なし |

### 配信時間帯

制限なし（アプリケーション起動時に即座に表示）

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

- 本通知は外部への送信を行わないため、情報漏洩のリスクはない
- レジストリ読み取りは読み込み専用で行われる

## 備考

- 本通知はVB.NETのMsgError関数を使用して実装されている
- 通知後は自動的にポータブルモードに切り替わるため、処理は続行可能
- AviSynthのインストール検出はレジストリのCOM登録とDLLファイルの存在確認で行われる
- No.70（VapourSynth未検出エラー）と同様のパターンで実装されている

---

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

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

### 推奨読解順序

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

FrameServerHelpクラスとAviSynth検出ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | FrameServer.vb | `Source/Video/FrameServer.vb` | FrameServerHelpクラス、IsAviSynthPortable、GetAviSynthInstallPath |
| 1-2 | FrameServer.vb | `Source/Video/FrameServer.vb` | FrameServerMode列挙型（Portable, Installed, VFW） |

**読解のコツ**: GetAviSynthInstallPath()はレジストリのCLSIDキーからInProcServer32を取得。パスが"AviSynth.dll"のみの場合はSystem32パスと結合。

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

OnActivatedイベントハンドラを特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | MainForm.vb | `Source/Forms/MainForm.vb` | OnActivatedメソッド（行5929-5950） |

**主要処理フロー**:
1. **行5930**: MyBase.OnActivated呼び出し
2. **行5931**: UpdateNextButton呼び出し
3. **行5933-5936**: AviSynthインストールチェックと通知表示（本通知の発火点）
4. **行5934**: MsgError表示
5. **行5935**: s.AviSynthMode = FrameServerMode.Portable

#### Step 3: 通知表示関数を理解する

MsgError関数の実装を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | General.vb | `Source/General/General.vb` | MsgError関数（行1222-1241） |

**主要処理フロー**:
- **行1222**: MsgError関数定義
- **行1236**: ShowCopyButton = True

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

```
MainForm.OnActivated(e)
    │
    ├─ MyBase.OnActivated(e)
    │
    ├─ UpdateNextButton()
    │
    ├─ [AviSynthチェック]
    │      │
    │      ├─ FrameServerHelp.IsAviSynthPortable
    │      │      └─ s.AviSynthMode = FrameServerMode.Portable ?
    │      │
    │      └─ [False の場合]
    │             │
    │             └─ FrameServerHelp.GetAviSynthInstallPath()
    │                    │
    │                    ├─ Registry.ClassesRoot.GetString(CLSID\...\InProcServer32)
    │                    │
    │                    └─ [空文字列の場合]
    │                           │
    │                           ├─ MsgError() [MainModule]
    │                           │      └─ TaskDialog表示
    │                           │
    │                           └─ s.AviSynthMode = FrameServerMode.Portable
    │
    └─ [VapourSynthチェック] ※No.70参照
```

### データフロー図

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

s.AviSynthMode ─────────▶ IsAviSynthPortable判定
        │
        ├─ [Portable] ──▶ チェックスキップ
        │
        └─ [Installed/VFW]
               │
               ▼
        GetAviSynthInstallPath()
               │
               ├─ レジストリCLSID検索
               │
               └─ DLLパス取得
                      │
                      ├─ [有効パス] ──▶ 正常終了
                      │
                      └─ [空文字列]
                             │
                             ▼
                      MsgError() ──▶ エラーダイアログ表示
                             │
                             ▼
                      s.AviSynthMode = Portable ──▶ モード変更
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| MainForm.vb | `Source/Forms/MainForm.vb` | ソース | メインフォームとOnActivatedイベント |
| General.vb | `Source/General/General.vb` | ソース | MsgError関数を含む汎用モジュール |
| FrameServer.vb | `Source/Video/FrameServer.vb` | ソース | FrameServerHelpとインストール検出 |
| Settings.vb | `Source/General/Settings.vb` | ソース | AviSynthMode設定の定義 |
| TaskDialog.vb | `Source/UI/TaskDialog.vb` | ソース | ダイアログ表示のUIコンポーネント |
