# バッチ設計書 50-Merge-TerminalAndXamlResources.ps1

## 概要

本ドキュメントは、TerminalとXAMLのリソース（PRI）をmakepri.exeで統合するPowerShellスクリプト「Merge-TerminalAndXamlResources.ps1」のバッチ設計書である。

### 本バッチの処理概要

展開されたTerminal AppXとXAML AppXのリソース（resources.pri）を統合する。TerminalのPRIをXMLダンプに変換し、XAML由来のMicrosoft.UI.Xamlリソースサブツリーを除去した上で、Merge-PriFiles.ps1を呼び出してTerminal XMLダンプとXAML PRIを1つのresources.priに統合する。

**業務上の目的・背景**：Windows TerminalはMicrosoft.UI.Xaml（WinUI）を使用しているが、TerminalとXAMLの両方がMicrosoft.UI.Xamlリソースを含む場合にリソースの衝突が発生する。本バッチはTerminal側のPRIからMicrosoft.UI.Xamlサブツリーを除去してからXAML PRIとマージすることで、リソース衝突を防止しつつ両方のリソースを1つのファイルに統合する。この処理はNew-UnpackagedTerminalDistribution.ps1（No.46）のポータブル版作成においても重要な工程である。

**バッチの実行タイミング**：ビルドプロセスのパッケージング工程において、Terminal AppXとXAML AppXが展開された後に実行される。New-UnpackagedTerminalDistribution.ps1（No.46）から呼び出される。

**主要な処理内容**：
1. 一時ディレクトリを作成する
2. TerminalのPRIをmakepri.exe dumpでXMLダンプ（detailed形式）に変換する
3. XMLダンプからMicrosoft.UI.Xamlリソースサブツリーを検索・除去する
4. XMLダンプからインデックス名を取得する
5. Merge-PriFiles.ps1を呼び出し、Terminal XMLダンプとXAML PRIを統合する
6. 一時ディレクトリをクリーンアップする

**前後の処理との関連**：New-UnpackagedTerminalDistribution.ps1（No.46）から呼び出される。内部でMerge-PriFiles.ps1（No.49）を呼び出す。入力となるresources.priは各AppXパッケージの展開結果に含まれる。

**影響範囲**：出力されるresources.priはポータブル版ディストリビューションの一部となる。リソース統合の不備はアプリケーションのUI表示に直接影響する。

## バッチ種別

リソース管理（リソース統合）

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（ビルド時） |
| 実行時刻 | ビルドプロセス依存 |
| 実行曜日 | 該当なし |
| 実行日 | 該当なし |
| トリガー | New-UnpackagedTerminalDistribution.ps1からの呼び出し／手動 |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| makepri.exeの存在 | MakePriPathで指定されたパスにmakepri.exeが存在すること |
| Windows SDK | Windows 10 SDK (10.0.22621.0) がインストールされていること（デフォルトパス使用時） |
| Terminal resources.priの存在 | TerminalRoot配下にresources.priが存在すること |
| XAML resources.priの存在 | XamlRoot配下にresources.priが存在すること |
| Merge-PriFiles.ps1の存在 | 同一ディレクトリ（$PSScriptRoot）にMerge-PriFiles.ps1が存在すること |

### 実行可否判定

$ErrorActionPreference = 'Stop'が設定されており、エラー発生時は即座にスクリプトが停止する。MakePriPathはValidateScriptでファイル存在チェックが行われる。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| TerminalRoot | string[] | Yes | なし | 展開されたTerminal AppXのルートディレクトリ |
| XamlRoot | string[] | Yes | なし | 展開されたXAML AppXのルートディレクトリ |
| OutputPath | string | Yes | なし | 出力PRIファイルのパス |
| MakePriPath | string | No | C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\MakePri.exe | makepri.exeのパス。ValidateScriptでファイル存在チェック |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| Terminal resources.pri | .pri | Terminal AppXのリソースインデックスファイル |
| XAML resources.pri | .pri | Microsoft.UI.Xaml AppXのリソースインデックスファイル |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| OutputPathで指定されたファイル | .pri | TerminalとXAMLのリソースが統合されたPRIファイル |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | OutputPathパラメータで指定（通常resources.pri） |
| 出力先 | OutputPathパラメータで指定 |
| 文字コード | バイナリ（PRI形式） |
| 区切り文字 | 該当なし |

## 処理フロー

### 処理シーケンス

```
1. 一時ディレクトリ作成
   └─ ランダムな名前の一時ディレクトリを作成（tmp{4桁16進数}.tmp形式）
2. Terminal PRIのXMLダンプ
   └─ makepri.exe dump /if {TerminalRoot}/resources.pri /of {一時ディレクトリ}/terminal.pri.xml /dt detailed
3. Microsoft.UI.Xamlサブツリー除去
   ├─ XMLドキュメントとして読み込み
   ├─ ResourceMap > ResourceMapSubtree[name="Files"] を取得
   ├─ Files配下のResourceMapSubtree[name="Microsoft.UI.Xaml"] を検索
   ├─ 存在する場合はRemoveChildで除去
   └─ 変更後のXMLを保存
4. インデックス名取得
   └─ PriInfo.ResourceMap.name属性を取得
5. Merge-PriFiles.ps1呼び出し
   └─ -Path {Terminal XMLダンプ}, {XAML resources.pri} -IndexName {インデックス名} -OutputPath {出力パス} -MakePriPath {makepri.exeパス}
6. 一時ディレクトリクリーンアップ
   └─ Remove-Item -Recurse -Force で削除
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[一時ディレクトリ作成]
    B --> C[makepri.exe dumpでTerminal PRIをXMLダンプ]
    C --> D[XMLドキュメントとして読み込み]
    D --> E[Files/Microsoft.UI.Xamlサブツリー検索]
    E --> F{サブツリー存在?}
    F -->|あり| G[RemoveChildで除去・XML保存]
    F -->|なし| H[スキップ]
    G --> I[インデックス名取得]
    H --> I
    I --> J[Merge-PriFiles.ps1呼び出し]
    J --> K[一時ディレクトリ削除]
    K --> L[バッチ終了]
```

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

### 操作別データベース影響一覧

本バッチはデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| N/A | パラメータ検証エラー | MakePriPathのValidateScriptでファイル存在チェック失敗 | 正しいmakepri.exeのパスを指定する |
| N/A | PRIダンプ失敗 | makepri.exe dumpが失敗 | Terminal resources.priの整合性を確認する |
| N/A | XML解析エラー | ダンプされたXMLが不正 | PRIダンプの内容を確認する |
| N/A | Merge-PriFiles.ps1エラー | リソース統合が失敗 | 入力PRIファイルの整合性を確認する |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし（リトライ機構なし） |
| リトライ間隔 | 該当なし |
| リトライ対象エラー | 該当なし |

### 障害時対応

makepri.exeのエラー出力を確認し、入力PRIファイルの整合性を検証する。Microsoft.UI.Xamlサブツリーの除去が正しく行われているかXMLダンプを確認する。

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | 該当なし（makepri.exeによる一括処理） |
| コミットタイミング | Merge-PriFiles.ps1完了時 |
| ロールバック条件 | 該当なし |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 2つのPRIファイル（Terminal + XAML） |
| 目標処理時間 | 数秒〜数十秒 |
| メモリ使用量上限 | XMLダンプサイズとmakepri.exeに依存 |

## 排他制御

一時ディレクトリにランダムな名前を使用して衝突を回避している。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| Verbose | Microsoft.UI.Xamlサブツリー除去時 | "Removing Microsoft.UI.Xaml node from Terminal to prevent a collision with XAML" |
| makepri.exe出力 | dump実行時 | makepri.exeの標準出力 |

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| ビルドエラー | 発生時 | ビルドシステム（CI/CD） |

## 備考

- Microsoft.UI.Xamlサブツリーの除去は、TerminalとXAMLの両方が同じXAMLリソースを含むことによる衝突を防止するための重要な処理である。
- サブツリーが存在しない場合（$Null -Ne チェック）はスキップされるため、XAMLリソースを含まないTerminal PRIにも対応可能。
- Write-Verboseでサブツリー除去の処理を通知しており、-Verboseスイッチで確認可能。
- インデックス名はTerminal PRIのResourceMap.name属性から取得され、Merge-PriFiles.ps1に渡される。これにより出力PRIが元のTerminalと同じインデックス名を維持する。
- Merge-PriFiles.ps1の呼び出しは$PSScriptRoot（同一ディレクトリ）を基準としたJoin-Pathで行われる。
- TerminalRootとXamlRootはstring[]型だが、通常は1つのパスが渡される。
- ソースファイルパス: `build/scripts/Merge-TerminalAndXamlResources.ps1`
