# XP.Installer ## Branding resources Product branding is centralized in `Branding`. Update these files for a new product identity: - `MsiProductIcon.ico` — MSI product icon - `BundleIcon.ico` — Burn bundle and WPF icon - `ProductIcon.png` — WPF installer product image - `CompanyLogo.jpg`, `ProductLogo.jpg`, `ProductLogoHeader.jpg` — MSI logos - `Splash.bmp` — bundle splash screen - `License\\` — localized license files The MSI, Burn bundle, and WPF installer projects reference these files directly. The old resource folders retain only generic installer resources. 独立的 WiX 安装包解决方案,采用“两层式安装包”结构: ```text BundleInstaller.exe(外层 Bootstrapper/Bundle) └── Installer.msi(内层 MSI 安装包) ``` ## 解决方案与项目 - 解决方案:`XP.Installer.sln` - 配置:`Release | x64` - 最终输出:`Setup\BundleInstaller\bin\x64\Release\BundleInstaller.exe` - MSI 输出:`Setup\BundleInstaller\bin\x64\Release\Installer.msi` 解决方案包含 4 个项目: | 项目 | 类型 | 作用 | |---|---|---| | `CustomActions` | C# 类库 | 许可证选择、授权检测和 MSI 自定义操作 | | `Product_Main` | WiX MSI 项目 | 生成 `Installer.msi`,安装产品文件、目录、快捷方式、注册表和 MSI UI | | `Bootstrapper.Ui` | C# WPF 类库 | 提供欢迎页、许可证页、进度页、升级提示等安装向导界面 | | `Bootstrapper` | WiX Bundle 项目 | 将 MSI、前置依赖和 WPF UI 组合为最终的 `BundleInstaller.exe` | 依赖关系: ```text CustomActions ↓ Product_Main(Installer.msi) ↓ Bootstrapper.Ui ↓ Bootstrapper(BundleInstaller.exe) ``` 最终用户通常运行 `BundleInstaller.exe`。直接运行 `Installer.msi` 不包含完整的 Bundle 前置依赖检测和自定义引导界面。 ## 构建要求 - Visual Studio 2022 - WiX Toolset 3.x 及 Votive 扩展 - `Setup\BundleInstaller\packages` 中的本地构建依赖 - `ReleaseFiles` 目录及 `ReleaseFiles.generated.wxs` 中声明的发布文件 仓库根目录的 `NuGet.Config` 将 `packages.config` 的还原目录固定为 `Setup\BundleInstaller\packages`,并配置本地 `Hex.Wix.Xeam.1.2.6` 源。顶层方案还原时请使用该配置,避免 NuGet 错误地到 `XP.Installer\packages` 或 nuget.org 查找 Xeam 私有包。 ## 目录职责 `XP.Installer` 是“通用安装框架 + 当前产品定制内容”的组合。 ### 与待打包软件直接相关 | 路径 | 作用 | |---|---| | `Setup\BundleInstaller\ReleaseFiles.generated.wxs` | 根据发布目录生成的产品文件清单,不建议手工编辑 | | `Setup\BundleInstaller\ProjectDefaults.wxi` | 产品名、版本、厂商、升级 GUID 和前置依赖开关 | | `Setup\BundleInstaller\UIresource\` | 产品 Logo、安装背景、按钮和图标 | | `Setup\BundleInstaller\CustomActions\` | HASP/LMS 许可证选择和授权相关逻辑 | | `Setup\BundleInstaller\WPFInstaller\Dependencies\` | 授权、硬件锁和安装辅助 DLL | | `Setup\BundleInstaller\WPFInstaller\Resources\` | Bundle 图标、启动图、许可证文本等资源 | | `Setup\BundleInstaller\WPFInstaller.Ui\` | 产品化安装向导页面、主题、文本和许可证流程 | | `Setup\Webupdater\UpdaterFiles.wxs` | WebUpdater/联网升级文件清单,结构可复用但内容属于产品 | 换产品时,不能只修改产品名称;至少需要重新确认 `ProjectDefaults.wxi`、生成文件清单、`Bundle.wxs`、许可证逻辑、升级 GUID 和品牌资源。 ### 通用安装工程基础设施 | 路径 | 作用 | |---|---| | `Product_Main.wixproj` | WiX MSI 构建配置 | | `WPFInstaller\Bootstrapper.wixproj` | WiX Burn Bundle 构建配置 | | `WPFInstaller.Ui\Bootstrapper.Ui.csproj` | WPF 安装向导构建配置 | | `Setup.wxs`、`UI_Texts.wxs` | MSI 安装目录、UI 序列、文本和自定义操作编排 | | `WPFInstaller\Bundle.wxs` | Burn 安装链、MSI、前置依赖和自定义 UI 编排 | | `Defines.wxi` | 环境变量与默认值之间的 WiX 预处理变量桥接 | | `ReleaseFilesRoot.wxs` | 发布文件目录的 WiX 根节点和变量入口 | | `Setup\Scripts\` | CI/批处理构建参数和自动化脚本 | | `Resource\InstallUtils.dll` | 安装过程使用的辅助组件,是否能跨产品复用需单独确认 | ### 开发工具、依赖和生成文件 - `Votive2022.vsix`、`wix314.exe`:WiX 开发环境安装包,不会装入最终产品。 - `WixEdit\binaries\`:可选的 WiX 文件清单辅助工具;当前 XplorePlane 打包链不依赖它。 - `Setup\BundleInstaller\packages\`:WiX、Xeam 和 WPF 构建依赖,不是待打包业务软件。 - `bin\`、`obj\`、`.vs\`:构建输出和 Visual Studio 缓存,不应作为源文件维护。 ## 关键机制 ### 变量与版本控制 `ProjectDefaults.wxi` 使用 `` 声明产品名称、版本、厂商、ProductCode、UpgradeCode、BundleUpgradeCode 和前置依赖开关;`Defines.wxi` 提供“环境变量优先,否则使用默认值”的兜底逻辑,供 `Setup\Scripts\DefaultVariables.bat` 或 CI 使用。 ### 产品文件清单 `ReleaseFilesRoot.wxs` 定义应用安装根目录,`ReleaseFiles.generated.wxs` 根据 `D:\XplorePlane\ReleaseFiles` 生成产品文件和子目录清单;发布文件最终直接安装到 `APPLICATIONFOLDER`。换机器或换版本时,应先准备新的 `ReleaseFiles` 发布目录,再重新生成该文件。 可以使用 `Setup\Scripts\Generate-ReleaseFilesWxs.ps1` 自动生成文件清单: ```powershell powershell -ExecutionPolicy Bypass -File .\XP.Installer\Setup\Scripts\Generate-ReleaseFilesWxs.ps1 ``` 脚本使用 WiX `heat.exe` 扫描 `ReleaseFiles`,输出到 `Setup\BundleInstaller\ReleaseFiles.generated.wxs`。默认使用 `-ag`,由 WiX 在编译时生成组件 GUID,避免重复执行脚本时随机改变 GUID,影响 MSI 升级。特殊目录或需要人工检查时,仍可使用 `WixEdit\binaries\WixEdit.exe` 的 `Import directory` 功能。 ### 许可证逻辑 MSI 层由 `CustomActions\CustomAction.cs` 的 `HandleLicenseChoice` 调用 WinForms 许可证选择窗口;Bundle 层由 `WPFInstaller.Ui\LicenseChoiceViewModel.cs` 通过 `WriteVariableToBundle` 写入 Bundle 变量。两者通过 `Resource\InstallUtils.dll` 执行实际授权检测或写入。 ### Bundle 安装链与自定义 UI `WPFInstaller\Bundle.wxs` 按 `ProjectDefaults.wxi` 中的 `INCLUDE_*` 开关注册 Windows Installer、VC++、.NET、SQL Server Express 等前置包,最后加入内层 MSI。`WPFInstaller.Ui` 集成 `Hex.Wix.Xeam.1.2.6` 提供的 Xeam Visual Installer,通过 `VisualInstallerConfig.xml` 配置页面顺序、主题和许可证页面。 ## 手动打包流程 以打包 XplorePlane 软件为例: 1. 确认 `D:\XplorePlane\ReleaseFiles` 中的 XplorePlane 发布文件已准备好。 2. 运行 `Setup\Scripts\Generate-ReleaseFilesWxs.ps1` 自动生成文件清单;如需人工处理,再使用 WixEdit 导入目录。 3. 用 Visual Studio 打开 `XP.Installer.sln`。 4. 修改 `ProjectDefaults.wxi` 中的产品名、版本号、厂商和 GUID。 5. 替换 `UIresource`、`WPFInstaller\Resources`、`WPFInstaller.Ui\Resources` 中的产品图标、Logo、启动图和许可证文件。 6. 切换到 `Release | x64`,重新生成解决方案。 7. 从 `Setup\BundleInstaller\bin\x64\Release\BundleInstaller.exe` 获取最终安装包。 ## 注意事项 - `CustomActions\bin\x64\Release\CustomActions.CA.dll` 被 `Setup.wxs` 硬编码引用;修改自定义操作后必须先重新生成 `CustomActions`。 - 修改 GUID 时要区分升级版本和全新产品。保持相同 UpgradeCode 才能形成同一升级链,全新品牌通常需要新 GUID。 - `Product_Main.wixproj` 中的 `ReleaseFilesSource` 当前指向 `D:\XplorePlane\ReleaseFiles`;换机器时应通过构建变量改为实际发布目录。 - 生成的 MSI 和 Bundle 必须使用同一配置、平台和版本信息。