- unattend.xml: DiskID 由硬寫 0 改成 $$VT_WINDOWS_DISK_1ST_NONVTOY$$, 防止在 Ventoy 下把 USB 本身當成安裝目標 - ventoy.json: 新增 Auto Install plugin 設定範本 - QUICKSTART.md: 用 Ventoy 流程重寫 USB 佈置與 VM 測試章節 - README.md: 放置位置表新增 Ventoy 路徑為預設 - CLAUDE.md: 新增專案導覽文件,標註 Ventoy-only 前提與 DiskID 變數 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
51 lines
5.2 KiB
Markdown
51 lines
5.2 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Repository nature
|
|
|
|
This is a **configuration template repo**, not a code project. It ships two artifacts:
|
|
|
|
- `unattend.xml` — the Windows Setup answer file.
|
|
- `ventoy.json` — the Ventoy Auto Install plugin config that tells Ventoy which ISO to pair with which template.
|
|
|
|
Deployment is via **[Ventoy](https://www.ventoy.net/)**, not Rufus or direct ISO modification. The user keeps a Ventoy USB with multiple Windows ISOs; `ventoy.json` at `/ventoy/ventoy.json` on the USB and `unattend.xml` at `/ventoy/script/unattend.xml` let Ventoy inject the answer file at boot without touching the ISO. Assume this Ventoy-based flow when reasoning about deploy-time behavior.
|
|
|
|
There is no build, no test suite, no package manager, and no runtime. Changes are validated by:
|
|
|
|
1. **Schema validation** via Windows SIM (Windows System Image Manager, part of Windows ADK).
|
|
2. **End-to-end VM test**: boot a VM from the Ventoy USB (or a Ventoy VHD) and confirm the install reaches the desktop without prompts. `QUICKSTART.md` has the exact steps.
|
|
|
|
There is no way to "run" this repo on the dev machine (macOS). All verification happens on a Windows target.
|
|
|
|
## The three-pass mental model
|
|
|
|
`unattend.xml` is not a flat config — it is split into three `<settings pass="...">` blocks that correspond to **three distinct moments in Windows Setup**. Each setting has a required pass; putting it in the wrong pass means Windows silently ignores it.
|
|
|
|
| Pass | When it runs | System state | What lives here |
|
|
|---|---|---|---|
|
|
| `windowsPE` | Booted from USB, Windows not yet installed | In-memory mini-OS | Disk partitioning, image selection, product key, EULA, WinPE UI language |
|
|
| `specialize` | Image applied, before first boot | `C:\` exists, no users yet | Computer name, timezone, registered owner, domain join |
|
|
| `oobeSystem` | First boot, OOBE running | Full Windows, waiting for account | Local account creation, AutoLogon, `FirstLogonCommands`, OOBE screen skips |
|
|
|
|
**Language settings appear twice on purpose** — once in `windowsPE` (`International-Core-WinPE`) for the installer UI, once in `oobeSystem` (`International-Core`) for the OOBE UI. That is not duplication; removing either will surface an unwanted language prompt.
|
|
|
|
## Non-obvious constraints when editing
|
|
|
|
- **Deployment is via Ventoy, not filename-based auto-detection.** The old "rename to `autounattend.xml` at USB root" trick does *not* apply here — Ventoy boots the ISO directly and injects the template per `ventoy.json`. Keep the repo filename as `unattend.xml` and keep the `ventoy.json` `template` path in sync.
|
|
- **`DiskID` uses the Ventoy variable `$$VT_WINDOWS_DISK_1ST_NONVTOY$$`, not a numeric literal.** Ventoy's Auto Install plugin substitutes this at runtime with the first non-Ventoy disk, so Windows doesn't wipe the Ventoy USB itself. **Never replace it with `0` or any hardcoded number.** Other Ventoy-provided variables (`$$VT_WINDOWS_DISK_MAX_SIZE$$`, `$$VT_WINDOWS_DISK_CLOSEST_<N>$$`) are valid substitutes for different selection policies but only work under Ventoy — they are meaningless if the XML is ever deployed via a non-Ventoy path.
|
|
- **Passwords appear twice**: once in `UserAccounts/LocalAccount` and once in `AutoLogon`. Both must match — changing one silently breaks AutoLogon.
|
|
- **`FirstLogonCommands` only fires if `AutoLogon.Enabled=true`**. Removing AutoLogon also disables the post-install script hand-off.
|
|
- **`Order` values within `FirstLogonCommands` / `CreatePartitions` / `ModifyPartitions` must be unique and contiguous** — duplicates cause silent skips.
|
|
- **The disk config assumes UEFI+GPT and wipes the selected disk unconditionally** (`WillWipeDisk=true`). Any BIOS/MBR target requires rewriting `<DiskConfiguration>`; there is no runtime branching.
|
|
- **`processorArchitecture="amd64"`** is hardcoded on every `<component>`. ARM64 deployments require a global find-and-replace to `arm64`.
|
|
- **Password is plaintext** (`<PlainText>true</PlainText>`). This is a deliberate testing-only choice documented in `SUMMARY.md`. For production, generate Base64 via Windows SIM; do not hand-encode.
|
|
- **`%RAND:5%`** in `ComputerName` is a Windows Setup built-in, not a shell variable — don't try to "fix" it. (Distinct from `$$VT_*$$` which is a Ventoy pre-processor substitution.)
|
|
- **`FirstLogonCommands` references `C:\Scripts\Setup.ps1`** but this repo does **not** contain that script. It is expected to be placed on the target by other means (baked into the image, copied from USB earlier in `FirstLogonCommands`, or pulled from network).
|
|
|
|
## When making changes
|
|
|
|
- Preserve the `xmlns="urn:schemas-microsoft-com:unattend"` namespace and the `wcm:action="add"` attributes on list items — Windows SIM emits these and Setup requires them.
|
|
- Every `<component>` needs all four identity attributes: `name`, `processorArchitecture`, `publicKeyToken="31bf3856ad364e35"`, `language="neutral"`, `versionScope="nonSxS"`.
|
|
- The Chinese-language docs (`README.md`, `QUICKSTART.md`, `SUMMARY.md`) explain the *why* behind design decisions — consult `SUMMARY.md` before proposing structural changes, as several current choices are explicit tradeoffs, not oversights.
|