feat(msi): give a template its own cabinet for per-customer files

Rebranding recompressed the whole ~100MB payload because one cabinet held
everything. In template mode preprocess.py puts the handful of files a custom
client replaces on a second cabinet, so a patch rebuilds a few hundred KB and
leaves the payload cabinet alone. The shipped msi is built without template
mode and keeps its single cabinet.

The branding assets need conditional components. A stock build ships none of
them -- there is no icon.ico, icon.png or logo*.png, only icon.svg -- so the
template has to carry placeholders for the File rows to exist, and a customer
supplies whichever they want. Installing a placeholder unconditionally would
give a customer with no logo a placeholder image, where today a missing asset
means no logo at all: the client tries each candidate and treats the failure as
absence. So each optional asset installs only when its property says the
customer supplied one.

CI creates those placeholders and builds the template with the new mode.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q7fBdTwziR5BHTkSz7Tzcm
This commit is contained in:
rustdesk
2026-08-05 22:02:51 +08:00
parent 0e4bff61e0
commit a2d4e742c7
3 changed files with 125 additions and 7 deletions

View File

@@ -405,6 +405,11 @@ jobs:
# it also names payload that must never be renamed, such as librustdesk.dll
# and drivers\RustDeskPrinterDriver.
#
# --template also puts the files a custom client replaces in their own
# cabinet, so rebranding rebuilds a few hundred KB rather than recompressing
# the whole payload. The shipped msi above is built without it and is
# unaffected.
#
# Building the arm64 template on the native arm64 runner is what makes ARM
# custom clients possible at all: the build agents are x64 and cannot run
# preprocess.py against an ARM exe.
@@ -413,8 +418,18 @@ jobs:
git checkout -- res/msi
cp -r ./rustdesk ./rustdesk-msi-template
mv ./rustdesk-msi-template/rustdesk.exe ./rustdesk-msi-template/RDAPPNAM.exe
# A stock build ships none of the files a custom client replaces, so the
# template needs a placeholder for each to have a File row to patch. The
# branding assets install only when the patcher says the customer supplied
# one, so an unused placeholder is never installed.
Set-Content -Path ./rustdesk-msi-template/custom.txt -Value 'placeholder' -NoNewline
$assets = './rustdesk-msi-template/data/flutter_assets/assets'
New-Item -ItemType Directory -Force -Path $assets | Out-Null
foreach ($a in 'icon.ico','icon.png','logo.png','logo_light.png','logo_dark.png') {
Set-Content -Path "$assets/$a" -Value 'placeholder' -NoNewline
}
pushd ./res/msi
python preprocess.py --arp -d ../../rustdesk-msi-template --app-name RDAPPNAM
python preprocess.py --arp --template -d ../../rustdesk-msi-template --app-name RDAPPNAM
$msiPlatform = if ('${{ matrix.job.arch }}' -eq 'aarch64') { 'ARM64' } else { 'x64' }
msbuild msi.sln -t:clean -p:Configuration=Release -p:Platform=$msiPlatform
msbuild msi.sln -p:Configuration=Release -p:Platform=$msiPlatform /p:TargetVersion=Windows10