XP.Installer
独立的 WiX 安装包解决方案,采用“两层式安装包”结构:
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 |
依赖关系:
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 使用 <?define ?> 声明产品名称、版本、厂商、ProductCode、UpgradeCode、BundleUpgradeCode 和前置依赖开关;Defines.wxi 提供“环境变量优先,否则使用默认值”的兜底逻辑,供 Setup\Scripts\DefaultVariables.bat 或 CI 使用。
产品文件清单
ReleaseFilesRoot.wxs 定义 APPLICATIONFOLDER\ReleaseFiles 目录,ReleaseFiles.generated.wxs 根据 D:\XplorePlane\ReleaseFiles 生成产品文件和子目录清单。换机器或换版本时,应先准备新的 ReleaseFiles 发布目录,再重新生成该文件。
许可证逻辑
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 软件为例:
- 确认
D:\XplorePlane\ReleaseFiles中的 XplorePlane 发布文件已准备好。 - 用 Visual Studio 打开
XP.Installer.sln。 - 修改
ProjectDefaults.wxi中的产品名、版本号、厂商和 GUID。 - 替换
UIresource、WPFInstaller\Resources、WPFInstaller.Ui\Resources中的产品图标、Logo、启动图和许可证文件。 - 切换到
Release | x64,重新生成解决方案。 - 从
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 必须使用同一配置、平台和版本信息。