无人值守安装与中文本土化配置总结

无人值守安装与中文本土化配置总结
无人值守安装与中文本土化配置总结概述本文档总结 ReactOS 无人值守Unattended安装机制的完整流程以及中文本地化SimSun 字体、区域设置的配置方法。涉及修改的文件涵盖bootcd.ini、unattend.inf、setuplib.c、reactos.c、reactos.dff.in、CMakeLists.txt、bootcd.ini等。1. 无人值守安装1.1 配置入口unattend.inf文件[bootcd/unattend.inf](file:///d:/reactos/boot/bootdata/bootcd/unattend.inf)无人值守安装通过unattend.inf文件驱动该文件必须在安装程序usetup.exe/reactos.exe的SourcePath中。关键配置项[Unattend] Signature $ReactOS$ ; 必须为 $ReactOS$ UnattendSetupEnabled yes ; 启用无人值守 DestinationDiskNumber 0 ; 目标磁盘号 DestinationPartitionNumber 1 ; 目标分区号 InstallationDirectory ReactOS ; 安装目录 BootLoaderLocation 2 ; 引导加载器位置2系统分区MBRVBR FormatPartition 1 ; 格式化分区 AutoPartition 1 ; 自动创建分区 FsType 0 ; 文件系统0FAT FullName User ; 用户名 OrgName Test ; 组织名 ComputerName REACTOS-PC ; 计算机名 TimeZoneIndex 210 ; 时区210北京时间/GMT8 DisableGeckoInst yes ; 禁用 Gecko 安装 LocaleID 804 ; 区域0x0804简体中文 ProductOption 1 ; 产品类型1工作站1.2 两阶段检测机制ReactOS 的安装分为两个阶段各阶段均需检测无人值守配置第一阶段unattend.inf文本模式安装 usetup.exeSourcePath\Device\CdRom0\i386从 CD-ROM 启动直接查找\Device\CdRom0\i386\unattend.inf第二阶段winntwinntwinnt.infGUI 安装 reactos.exe 从 VDI 启动后SourcePath\Device\Harddisk0\Partition1\ReactOS\system32从硬盘启动unattend.inf不在硬盘上需要回退到$winnt$.inf修改[setuplib.c#L30-L81](file:///d:/reactos/base/setup/lib/setuplib.c#L30)CheckUnattendedSetup(USETUP_DATA*pSetupData){// Step 1: 查找 SourcePath\unattend.infif(找到)gotoParseIt;// Step 2: 回退到 SourcePath\$winnt$.inf// $winnt$.inf 由 InstallSetupInfFile() 在第一阶段创建// 内容为原始 $winnt$.inf 基础上追加 unattend.inf 的完整内容CombinePaths(path,SourcePath,L$winnt$.inf);if(找到)gotoParseIt;returnFALSE;// 都不是 → 交互式安装}1.3winntwinntwinnt.inf 的生成文件[setuplib.c#L238-L396](file:////d:/reactos/base/setup/lib/setuplib.c#L238)InstallSetupInfFile()在第一阶段文件复制完成后被调用用IniCacheCreate()创建内存 INI 缓存写入[SetupParams]和[Data]段用IniCacheSave()保存到DestinationPath\System32\$winnt$.inf以追加模式打开该文件读取SourcePath\unattend.inf的原始内容追加到$winnt$.inf末尾结果文件内容示例[SetupParams] [Data] UnattendedInstall yes ProductType winnt SourcePath \Device\CdRom0\ [Unattend] Signature $ReactOS$ UnattendSetupEnabled yes ...1.4 分区选择修复文件[reactos.c#L1890-L1937](file:///d:/reactos/base/setup/reactos/reactos.c#L1890)在 GUI 安装第二阶段PrepareAndDoCopyThread()调用InitSystemPartition()之前需要确定InstallPartition。在交互模式下由DriveDlgProc设置无人值守模式下该页面被跳过InstallPartition保持 NULL导致InitSystemPartition访问 NULL 指针崩溃setuplib.dll偏移 0x00000008。修复添加无人值守分区自动选择逻辑if(IsUnattendedSetupInstallPartitionNULL){LONG DiskNumpSetupData-USetupData.DestinationDiskNumber;// 0LONG PartNumpSetupData-USetupData.DestinationPartitionNumber;// 1// 优先用 unattend.inf 的磁盘/分区号if(DiskNum0PartNum0)InstallPartitionSelectPartition(PartitionList,DiskNum,PartNum);// 回退AutoPartition 时选第一个已分区的条目if(InstallPartitionNULLpSetupData-USetupData.AutoPartition){InstallPartitionGetNextPartition(PartitionList,NULL);while(InstallPartition!InstallPartition-IsPartitioned)InstallPartitionGetNextPartition(PartitionList,InstallPartition);}// 仍然找不到 → 返回错误不再调用 InitSystemPartitionif(InstallPartitionNULL){PropSheet_SetWizButtons(...,PSWIZB_NEXT);return1;// 安全退出}}1.5 bootcd.ini 默认启动项文件[bootcd.ini](file:///d:/reactos/boot/bootdata/bootcd.ini)FreeLoader 的菜单默认启动项必须为Setup文本模式安装程序而非LiveImg_DebugLiveCD 调试模式-DefaultOSLiveImg_Debug DefaultOSSetup各启动项说明条目用途Setup文本模式安装程序usetup.exeLiveImgLiveCD 图形模式需配合/MININTSetup_Debug安装程序 COM1 串口调试LiveImg_DebugLiveCD COM1 串口调试1.6 unattend.inf 在 CD 上的位置文件[CMakeLists.txt](file:///d:/reactos/boot/bootdata/CMakeLists.txt)安装程序在SourcePath\unattend.inf查找无人值守配置。SourcePath为\Device\CdRom0\i386因此unattend.inf必须放在 CD 的\i386\目录下-add_cd_file(FILE .../bootcd/unattend.inf DESTINATION reactos ...) add_cd_file(FILE .../bootcd/unattend.inf DESTINATION i386 ...)DESTINATION reactos会放到\reactos\安装程序找不到DESTINATION i386放到\i386\才能被CheckUnattendedSetup发现。2. 中文本土化2.1 区域设置Localeunattend.inf中通过LocaleID 804指定简体中文0x0804。此值被CheckUnattendedSetup读取并存入USETUP_DATA.LocaleID随后用于选择安装过程中的默认语言usetup 界面设置HKLM\SYSTEM\CurrentControlSet\Control\Nls\Language注册表值第二阶段 GUI 的语言选择2.2 时区设置TimeZoneIndex 210对应北京时间GMT8:00无夏令时。该值被写入注册表HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation。2.3 SimSun 字体集成文件列表配置文件[reactos.dff.in](file:///d:/reactos/boot/bootdata/packages/reactos.dff.in)simsun.ttc位于modules/optional/目录。原标记为optional仅当文件存在时包含需要移除标记使其强制打包到reactos.cab-modules/optional/simsun.ttc 4 optional modules/optional/simsun.ttc 44对应 DFF 目录编号 4 Fonts安装时 CAB 管理器会将文件解压到%SystemRoot%\Fonts\simsun.ttc。字体检测机制文件[usetup.c#L103-L146](file:///d:/reactos/base/setup/usetup/usetup.c#L103)文本模式安装程序在文件复制过程中通过DoWatchDestFileName()监视目标文件名检测 CJK 字体文件staticFONTSUBSTSETTINGS s_SubstSettings{FALSE};staticvoidDoWatchDestFileName(LPCWSTR FileName){if(_wcsicmp(FileName,Lsimsun.ttc)0)s_SubstSettings.bFoundFontSIMSUNTRUE;// 标记 SimSun 可用if(_wcsicmp(FileName,Lmingliu.ttc)0)s_SubstSettings.bFoundFontMINGLIUTRUE;// ... msgothic, msmincho, gulim, batang 等}字体替换注册文件[mui.c#L564-L605](file:///d:/reactos/base/setup/lib/mui.c#L564)文件复制完成后DoRegistryFontFixup()根据检测结果向注册表写入字体替换DoRegistryFontFixup(s_SubstSettings,LangID){// 写入 FontSubstitutesMS Shell Dlg → SimSun, Tahoma → SimSunif(bFoundFontSIMSUN)AddFontsSettingsToRegistry(SimplifiedChineseFontFixup);// 如果 SIMSUN 不可用回退到 DroidSansFallback// 如果都不存在使用 FontLink\SystemLink 链式回退}字体替换表文件[muifonts.h](file:///d:/reactos/base/setup/lib/muifonts.h)// SimplifiedChineseFontFixup当检测到 simsun.ttc 时写入{LMS Shell Dlg,LSimSun},{LTahoma,LSimSun},// FontFixupSIMSUN当 simsun.ttc 存在时写入 FontLink\SystemLink{LSimSun,NULL},// SimSun 自身不需要替换{LNSimSun,NULL},// NSimSun 自身不需要替换2.4 键盘布局unattend.inf未直接指定键盘布局。第二阶段安装程序在InstallSetupInfFile()的$winnt$.inf中默认使用 US 键盘00000409。中文环境下需要在unattend.inf补充或通过hivesft.inf预设HKLM\...\Preload\100000804。3. 完整安装流程图┌───────────────────────────────────────────────────────────────────┐ │ 无人值守安装完整流程 │ ├───────────────────────────────────────────────────────────────────┤ │ │ │ ┌─ 创建 bootcd.iso ──────────────────────────────────────────┐ │ │ │ ninja -j 20 bootcd │ │ │ │ 产物: bootcd.iso (~475MB含 simsun.ttc) │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ ▼ │ │ ┌─ 第一阶段: CD-ROM 启动 ─────────────────────────────────────┐ │ │ │ FreeLoader → DefaultOSSetup → usetup.exe │ │ │ │ ├─ CheckUnattendedSetup() → 找到 \i386\unattend.inf │ │ │ │ │ → IsUnattendedSetup TRUE │ │ │ │ ├─ 自动创建分区、格式化(FAT) │ │ │ │ ├─ 从 reactos.cab 解压文件到 Harddisk0\Partition1\ReactOS\ │ │ │ │ │ └─ DoWatchDestFileName → 检测 simsun.ttc │ │ │ │ ├─ InstallSetupInfFile() → 追加 unattend 内容到 $winnt$.inf │ │ │ │ ├─ DoRegistryFontFixup() → 注册 SimSun 字体替换 │ │ │ │ ├─ 安装 FreeLoader 引导到 VDI 的 MBR/VBR │ │ │ │ └─ 重启 │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ ▼ │ │ ┌─ 第二阶段: VDI 启动 ────────────────────────────────────────┐ │ │ │ FreeLoader(VDI) → 引导 ReactOS 内核 │ │ │ │ → SMSS \SystemRoot\system32\smss.exe │ │ │ │ → 读取 SetupExecute / CmdLine 注册表值 │ │ │ │ → 启动 reactos.exe │ │ │ │ ├─ _tWinMain() → CheckUnattendedSetup() │ │ │ │ │ ├─ SourcePath\unattend.inf → 不存在(无 CD) │ │ │ │ │ └─ SourcePath\$winnt$.inf → 存在含 [Unattend] 段 │ │ │ │ │ → IsUnattendedSetup TRUE │ │ │ │ ├─ 跳过交互页面(Start/Type/Drive/Summary) │ │ │ │ ├─ PrepareAndDoCopyThread() │ │ │ │ │ └─ 自动选择 InstallPartition (Disk0, Partition1) │ │ │ │ ├─ InitSystemPartition() → 设置活动分区 │ │ │ │ ├─ 注册表更新、驱动安装 │ │ │ │ └─ 重启 → 完成安装 │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ ▼ │ │ ┌─ 第三阶段: 正常启动 ───────────────────────────────────────┐ │ │ │ FreeLoader → 引导 ReactOS │ │ │ │ ├─ 自动登录(AutoAdminLogon1) │ │ │ │ ├─ userinit → explorer.exe │ │ │ │ └─ 中文桌面 → SimSun 字体生效 │ │ │ └──────────────────────────────────────────────────────────────┘ │ └───────────────────────────────────────────────────────────────────┘4. 修改文件清单文件修改内容原因[bootcd/unattend.inf](file:///d:/reactos/boot/bootdata/bootcd/unattend.inf)启用UnattendSetupEnabledyes设置中文 LocaleID804自动化和中文本地化[bootcd.ini](file:///d:/reactos/boot/bootdata/bootcd.ini)DefaultOSSetup默认启动文本模式安装而非 LiveCD[CMakeLists.txt](file:///d:/reactos/boot/bootdata/CMakeLists.txt)DESTINATION i386unattend.inf 必须在 SourcePath 中[setuplib.c](file:///d:/reactos/base/setup/lib/setuplib.c)CheckUnattendedSetup添加$winnt$.inf回退第二阶段无 CD需从硬盘文件检测[reactos.c](file:///d:/reactos/base/setup/reactos/reactos.c)PrepareAndDoCopyThread添加分区自动选择防止 InstallPartitionNULL 崩溃[reactos.dff.in](file:///d:/reactos/boot/bootdata/packages/reactos.dff.in)移除simsun.ttc的optional标记强制包含 SimSun 字体5. 常见问题Q: 第二阶段弹出 reactos.exe 交互界面原因:CheckUnattendedSetup()返回 FALSEIsUnattendedSetupFALSE排查: 检查SourcePath下是否有unattend.inf或$winnt$.inf修复: 确保$winnt$.inf含[Unattend]段由InstallSetupInfFile生成定位方法: 串口日志中搜索(base/setup/lib/setuplib.c:xx)相关消息Q: 第二阶段 setuplib.dll 崩溃 (0x00000008)原因:InstallPartition为 NULLInitSystemPartition访问InstallPartition-DiskEntry修复: 在PrepareAndDoCopyThread中添加无人值守分区自动选择定位方法: 串口日志中搜索Unhandled exceptionsetuplib.dllQ: 中文显示方框/乱码原因: SimSun 字体未安装或注册表字体替换未生效排查: 1) 确认 C:\ReactOS\Fonts\simsun.ttc 存在 2) 确认bFoundFontSIMSUNTRUE3) 确认注册表HKLM\...\FontSubstitutes含MS Shell DlgSimSun修复: 在reactos.dff.in中移除simsun.ttc的optional标记Q: 启动后进入 LiveCD 而非安装程序原因:bootcd.ini的DefaultOS为LiveImg_Debug修复: 改为DefaultOSSetup定位方法: 串口日志ARC Paths: ...cdrom...表示从 CD 引导检查 FreeLoader 启动选项