PrintToVeraeTimeStamp/platform/windows/wix/README.md
George Lambert 86809b27eb
Some checks failed
windows-msi / full-msi-unsigned (push) Has been cancelled
feat: enable-printer-cas.ps1 unlocks deferred printer CAs for VM C
Toggles Product-Full markers; dual-ship-smoke reports C blocked until enabled.
2026-10-14 00:47:09 -04:00

10 KiB
Raw Blame History

Windows WiX packaging (tray + full MSI)

standard-readme compliant

WiX v3 authoring for (1) non-elevated tray presence MSI and (2) elevated full Print Stamp MSI (Product-Full.wxs + build-full-msi.ps1).

Neither package is commercial-ready yet (no Authenticode; full MSI printer CAs still commented stubs). Day-to-day tray without WiX: ../scripts/build-tray-startmenu.ps1. Full product GUI install remains NSIS (../installer-windows.nsi) until dual-ship validation (DUAL-SHIP.md). Commercial gaps: docs/COMMERCIAL-INSTALLER-BACKLOG.md.

Install

Requires WiX Toolset on a Windows host (or CI Windows runner). Without candle/light (or WiX v4 wix build), no MSI is produced — use the PowerShell Start Menu stub instead.

WiX v3 (this skeleton’s XML):

REM Add candle.exe + light.exe to PATH, e.g.:
REM set PATH=%PATH%;%ProgramFiles(x86)%\WiX Toolset v3.14\bin

WiX v4+ (dotnet tool install --global wix): adapt namespaces / Package element; authoring here is WiX v3.

Stage tray scripts from this repo before building:

set WIXDIR=platform\windows\wix
set STAGE=%WIXDIR%\Stage
mkdir %STAGE% 2>nul
copy /Y platform\windows\scripts\verae-tray.ps1 %STAGE%\
copy /Y platform\windows\scripts\common.ps1     %STAGE%\

Usage

What the package does

Item Behavior
Install scope perUser, InstallPrivileges=limited (no UAC)
Files %LocalAppData%\Verae\Tray\verae-tray.ps1 (+ common.ps1)
Start Menu Programs\Verae\Verae Tray.lnk → PowerShell STA + tray script
Startup Startup\Verae Tray.lnk (same idea as install-tray-startup.ps1)
IPP Unchanged — tray only uses GET /status / GET /queue

What it does not do

Elevated Program Files install, printers, scheduled helper, Authenticode, NSIS key wizard parity, machine-wide Start Menu under ProgramData.

Build (preferred): build-tray-msi.ps1

From platform/windows/scripts on Windows (or any cwd):

powershell -NoProfile -ExecutionPolicy Bypass -File platform\windows\scripts\build-tray-msi.ps1

The script:

  1. Resolves ProductVersion via Get-VeraePackageVersion → internal/job.HelperVersion (override with -Version or $env:VERSION).
  2. Stages verae-tray.ps1 + common.ps1 under wix/Stage.
  3. Runs candle + light when found on PATH / %WIX% / Program Files.
  4. Writes wix/out/VeraeTray-<version>-peruser.msi.
  5. If candle/light are missing, prints a WiX install tip and exits 0 (day-to-day tray path stays build-tray-startmenu.ps1).

build-tray-msi.ps1 exit codes

Code Meaning
0 MSI built successfully, or WiX (candle/light) not found and install tip printed (default; does not fail the non-WiX tray path).
1 Failure: -SkipTip when WiX is missing; missing product/fragment .wxs or verae-tray.ps1; candle or light returned non-zero; or a terminating PowerShell error.

CI that requires an MSI artifact should pass -SkipTip so a missing toolset fails the job.

Build (manual WiX v3 candle / light)

From repo root on Windows:

set WIXDIR=platform\windows\wix
set STAGE=%WIXDIR%\Stage
set OUT=%WIXDIR%\out
REM Prefer HelperVersion; build-tray-msi.ps1 does this automatically:
set VER=0.3.6

mkdir %STAGE% 2>nul
mkdir %OUT% 2>nul
copy /Y platform\windows\scripts\verae-tray.ps1 %STAGE%\
copy /Y platform\windows\scripts\common.ps1     %STAGE%\

candle.exe -nologo -out %OUT%\ ^
  -dProductVersion=%VER% ^
  -dStageDir=%CD%\%STAGE% ^
  %WIXDIR%\VeraeTrayShortcuts.wxs ^
  %WIXDIR%\VeraeTrayShortcutsFragment.wxs

light.exe -nologo -out %OUT%\VeraeTray-%VER%-peruser.msi ^
  %OUT%\VeraeTrayShortcuts.wixobj ^
  %OUT%\VeraeTrayShortcutsFragment.wixobj

Notes:

  • ProductVersion is wired by build-tray-msi.ps1 → Get-VeraePackageVersion / HelperVersion. Manual builds should pass -dProductVersion= the same way. The .wxs <?ifndef?> fallback is 0.3.6 (must match current HelperVersion).
  • Product Id="*" generates a new ProductCode per build; UpgradeCode is fixed for major-upgrade of this tray presence package only.
  • Skeleton is UI-less (silent-friendly). For WixUI_Minimal, uncomment UIRef / WixUILicenseRtf in VeraeTrayShortcuts.wxs, add License.rtf, and pass -ext WixUIExtension to light.

Silent install (per-user, no elevation):

msiexec /i VeraeTray-0.3.6-peruser.msi /qn VERAE_IPP_ADDR=127.0.0.1:8631

Uninstall via ARP (Verae Tray (presence)) or msiexec /x {ProductCode} /qn.

Full elevated MSI: build-full-msi.ps1

powershell -NoProfile -ExecutionPolicy Bypass -File platform\windows\scripts\build-full-msi.ps1

The script:

  1. Creates wix/StageFull/bin and wix/StageFull/scripts.
  2. Copies verae-print.exe / verae-printhelper.exe if found under -BinSource, dist/windows, or prior StageFull; otherwise Go-builds them (GOOS=windows, helper with -H windowsgui).
  3. Copies helper scripts from platform/windows/scripts and LICENSE/README when present.
  4. Resolves ProductVersion via Get-VeraePackageVersion → HelperVersion.
  5. Runs candle + light on Product-Full.wxs when WiX is found.
  6. Writes wix/out/VeraePrintStamp-windows-<arch>-<version>.msi.

build-full-msi.ps1 exit codes

Code Meaning
0 MSI built successfully (SkipLight: candle-only success).
1 WiX (candle/light) missing (clear error + install tip — not soft-OK like tray); missing Product-Full.wxs / binaries / scripts / docs; Go build failed; candle or light non-zero; terminating error.

Without WiX: StageFull is still prepared when binaries can be obtained, then the script exits 1 with the WiX install tip. Use NSIS (build-windows.ps1) for day-to-day full product. Not Authenticode-signed; printer CAs remain commented stubs (see Product-Full.wxs). Side-by-side NSIS+MSI validation: DUAL-SHIP.md.

Enable printer CAs (VM C)

Deferred printer/helper CustomActions in Product-Full.wxs ship disabled (wrapped in DEFERRED_PRINTER_CAS:OFF … DEFERRED_PRINTER_CAS:OFF comment markers) so candle/light stay files-only — safe for dual-ship VM B (VERAE_SKIP_PRINTERS=1). VM C is blocked until the body is enabled, MSI rebuilt, and clean-VM parity with NSIS is signed off.

# Status (default tree = disabled → dual-ship-smoke marks VM C BLOCKED)
powershell -NoProfile -ExecutionPolicy Bypass -File platform\windows\scripts\enable-printer-cas.ps1 -Status

# Enable CAs for VM C authoring (does not build/install/sign)
powershell -NoProfile -ExecutionPolicy Bypass -File platform\windows\scripts\enable-printer-cas.ps1

# Rebuild full MSI, then offline checklist (C no longer authoring-blocked)
powershell -NoProfile -ExecutionPolicy Bypass -File platform\windows\scripts\build-full-msi.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File platform\windows\scripts\dual-ship-smoke.ps1

# Re-disable (files-only default)
powershell -NoProfile -ExecutionPolicy Bypass -File platform\windows\scripts\enable-printer-cas.ps1 -Disable
Fact Detail
What enable does Unwraps CA defs + InstallExecuteSequence in Product-Full.wxs only
What it does not Build MSI, install printers, drive a VM, Authenticode, thin NSIS
dual-ship-smoke Prints VM C BLOCKED until CAs enabled; enabling is a prereq, not a pass
After enable Clean-VM C must match VM A (printers, helper task, skip prop) before dual-ship gate closes

Manual edit is fine: keep defs and schedule together; do not leave half-uncommented markers.

Files in this folder

File Role
VeraeTrayShortcuts.wxs Per-user tray Product + file components (ProductVersion)
VeraeTrayShortcutsFragment.wxs Start Menu + Startup shortcut fragment
Product-Full.wxs Elevated full product (bin/scripts/docs/Start Menu + silent props; CA schedule commented)
Product-Full.wxs.outline Full MSI checklist / staging layout
DUAL-SHIP.md NSIS + full MSI clean-VM dual-ship runbook
SILENT_PROPS.md Public msiexec /qn property contract
CI-SIGN-NOTARY.md Draft Authenticode + notarytool secret names only
README.md This file
../scripts/build-tray-msi.ps1 Tray candle/light driver; WiX tip exit 0 if missing
../scripts/build-full-msi.ps1 Full StageFull + candle/light; WiX missing → exit 1
../scripts/fill-manifest-sha256.ps1 Hash built MSI/NSIS → DOWNLOADS-MANIFEST row (no upload)
../scripts/dual-ship-smoke.ps1 Offline dual-ship checklist runner (print A/B/C; optional local hash)
../scripts/enable-printer-cas.ps1 Enable/disable deferred printer CAs in Product-Full.wxs (VM C prereq)
VM-DUAL-SHIP-CHECKLIST.md Printable clean-VM A/B/C tick sheet

Relation to other Windows paths

Path Role
../scripts/verae-tray.ps1 Runtime tray (source staged into tray MSI)
../scripts/install-tray-startup.ps1 WiX-free Startup shortcut
../scripts/build-tray-startmenu.ps1 WiX-free Start Menu + Startup
../scripts/build-tray-msi.ps1 Builds tray presence MSI when WiX is installed
../scripts/build-full-msi.ps1 Stages StageFull + builds full MSI when WiX is installed
../scripts/fill-manifest-sha256.ps1 Local SHA-256 rows for site DOWNLOADS-MANIFEST (no upload)
../scripts/dual-ship-smoke.ps1 Offline print of dual-ship A/B/C steps + optional MSI/NSIS verify/hash
../scripts/enable-printer-cas.ps1 Toggle deferred printer CAs in Product-Full (default off; VM C needs on)
../installer-windows.nsi Elevated full product setup.exe (primary until MSI validated)
wix/ (this folder) Tray skeleton + full Product-Full authoring

Commercial remaining: schedule printer CAs, Authenticode CI, Intune smoke, thin NSIS after dual-ship. Do not claim signed/notarized ship from this folder alone.

Contributing

Questions and packaging bugs: open an issue or PR against the PrintToVeraeTimeStamp tree. PRs accepted for WiX authoring that keep per-user / non-elevated tray scope separate from the full elevated product MSI. Do not commit certs, passwords, or signed binaries.

License

UNLICENSED © Verae