增加发布文件清单自动生成脚本

This commit is contained in:
zhengxuan.zhang
2026-08-06 15:23:30 +08:00
parent 5d4a488046
commit 2773024718
2 changed files with 69 additions and 5 deletions
+14 -5
View File
@@ -97,6 +97,14 @@ BootstrapperBundleInstaller.exe
`ReleaseFilesRoot.wxs` 定义 `APPLICATIONFOLDER\ReleaseFiles` 目录,`ReleaseFiles.generated.wxs` 根据 `D:\XplorePlane\ReleaseFiles` 生成产品文件和子目录清单。换机器或换版本时,应先准备新的 `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` 执行实际授权检测或写入。
@@ -110,11 +118,12 @@ MSI 层由 `CustomActions\CustomAction.cs` 的 `HandleLicenseChoice` 调用 WinF
以打包 XplorePlane 软件为例:
1. 确认 `D:\XplorePlane\ReleaseFiles` 中的 XplorePlane 发布文件已准备好。
2. 用 Visual Studio 打开 `XP.Installer.sln`
3. 修改 `ProjectDefaults.wxi` 中的产品名、版本号、厂商和 GUID
4. 替换 `UIresource``WPFInstaller\Resources``WPFInstaller.Ui\Resources` 中的产品图标、Logo、启动图和许可证文件
5. 切换到 `Release | x64`,重新生成解决方案
6. `Setup\BundleInstaller\bin\x64\Release\BundleInstaller.exe` 获取最终安装包
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` 获取最终安装包。
## 注意事项
@@ -0,0 +1,55 @@
[CmdletBinding()]
param(
[string]$ReleaseFilesRoot = (Join-Path $PSScriptRoot '..\..\..\ReleaseFiles'),
[string]$OutputFile = (Join-Path $PSScriptRoot '..\BundleInstaller\ReleaseFiles.generated.wxs'),
[string]$HeatPath = ''
)
$ErrorActionPreference = 'Stop'
$ReleaseFilesRoot = [System.IO.Path]::GetFullPath($ReleaseFilesRoot)
$OutputFile = [System.IO.Path]::GetFullPath($OutputFile)
if (-not (Test-Path -LiteralPath $ReleaseFilesRoot -PathType Container)) {
throw "Release files directory does not exist: $ReleaseFilesRoot"
}
if ([string]::IsNullOrWhiteSpace($HeatPath)) {
$heatCommand = Get-Command heat.exe -ErrorAction SilentlyContinue
if ($heatCommand) {
$HeatPath = $heatCommand.Source
} elseif ($env:WIX -and (Test-Path -LiteralPath (Join-Path $env:WIX 'heat.exe'))) {
$HeatPath = Join-Path $env:WIX 'heat.exe'
} else {
$defaultHeat = 'C:\Program Files (x86)\WiX Toolset v3.14\bin\heat.exe'
if (Test-Path -LiteralPath $defaultHeat) {
$HeatPath = $defaultHeat
} else {
throw 'heat.exe was not found. Install WiX Toolset 3.x or pass -HeatPath.'
}
}
}
$outputDirectory = Split-Path -Parent $OutputFile
New-Item -ItemType Directory -Path $outputDirectory -Force | Out-Null
# -ag lets WiX derive component GUIDs at compile time. Do not use -gg here:
# generating new GUIDs on every run would break MSI upgrade/component identity.
$heatArguments = @(
'dir', $ReleaseFilesRoot,
'-cg', 'ReleaseFilesComponents',
'-dr', 'RELEASEFILES',
'-ag',
'-srd',
'-sreg',
'-scom',
'-var', 'var.ReleaseFilesSource',
'-nologo',
'-out', $OutputFile
)
& $HeatPath @heatArguments
if ($LASTEXITCODE -ne 0) {
throw "heat.exe failed with exit code $LASTEXITCODE."
}
Write-Host "Generated: $OutputFile"