From fce4b77bd6cd09606c82a6d7898dd9e26791e5ea Mon Sep 17 00:00:00 2001 From: sysadmin Date: Wed, 10 Jun 2026 10:14:08 +0100 Subject: [PATCH] fix(collector): launch via Setup\CmdLine (was bypassed) + WinPE diagnostics The boot.wim Setup\CmdLine override (legacy-Setup forcing) is authoritative over winpeshl.ini, so it launched setup.exe directly and the collector never ran -- the VM went straight to the old sm-bootstrap unattended install. Repoint Setup\CmdLine at the collector (cmd /c X:\sm\Start-Collector.cmd); the collector still launches the legacy X:\sources\setup.exe itself. Add wpeinit + an on-screen banner, and write any collector/WinForms-load failure to X:\sm\collector-error.txt shown on the console before falling back, so we can diagnose WinForms-in-WinPE. Co-Authored-By: Claude Opus 4.8 --- windows/collector/Collector.ps1 | 5 ++++- windows/collector/Start-Collector.cmd | 19 +++++++++++++++---- windows/installer/build.ps1 | 9 +++++++-- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/windows/collector/Collector.ps1 b/windows/collector/Collector.ps1 index 1d2ae25..0580d21 100644 --- a/windows/collector/Collector.ps1 +++ b/windows/collector/Collector.ps1 @@ -250,6 +250,9 @@ try { [Environment]::Exit(1) } catch { - # Any failure -> exit 1 so Start-Collector.cmd falls back to the default answer file. + # Any failure (e.g. WinForms can't load in WinPE) -> log it where Start-Collector.cmd + # can show it on the console, then exit 1 so the wrapper falls back to the default answer file. + try { ($_ | Out-String) | Set-Content 'X:\sm\collector-error.txt' -Encoding ASCII } catch {} + Write-Host ('Collector error: ' + ($_ | Out-String)) [Environment]::Exit(1) } diff --git a/windows/collector/Start-Collector.cmd b/windows/collector/Start-Collector.cmd index 68e639a..10f0d66 100644 --- a/windows/collector/Start-Collector.cmd +++ b/windows/collector/Start-Collector.cmd @@ -1,15 +1,26 @@ @echo off set "SETUP=X:\sources\setup.exe" if not exist "%SETUP%" set "SETUP=X:\setup.exe" -REM WinPE entry point. SM_UNATTENDED=1 -> skip the UI and launch Setup with the default -REM answer file (used by CI / non-interactive builds). +REM WinPE entry point (launched via Setup\CmdLine). SM_UNATTENDED=1 -> skip the UI and +REM launch Setup with the default answer file (used by CI / non-interactive builds). if "%SM_UNATTENDED%"=="1" ( start /wait "%SETUP%" /unattend:X:\autounattend.xml exit /b 0 ) +REM Initialise WinPE (a Setup\CmdLine launch can bypass the normal startnet/wpeinit). +wpeinit +echo ============================================ +echo SilverMetal pre-config collector +echo ============================================ +del /f /q X:\sm\collector-error.txt 2>nul powershell -NoProfile -ExecutionPolicy Bypass -File X:\sm\Collector.ps1 -if errorlevel 1 ( - REM Collector failed or was cancelled -> fall back to the default answer file so install still proceeds. +set RC=%errorlevel% +if %RC% GEQ 1 ( + echo. + echo Collector exited with code %RC% -- falling back to default unattended install. + if exist X:\sm\collector-error.txt type X:\sm\collector-error.txt + echo (pausing ~25s so this is readable on the console) + ping -n 26 127.0.0.1 >nul start /wait "%SETUP%" /unattend:X:\autounattend.xml ) exit /b 0 diff --git a/windows/installer/build.ps1 b/windows/installer/build.ps1 index 6ae6410..bbf7d7c 100644 --- a/windows/installer/build.ps1 +++ b/windows/installer/build.ps1 @@ -130,8 +130,13 @@ function Invoke-ForceLegacySetup { Copy-Item (Join-Path $PSScriptRoot '..\collector\*') $smDir -Recurse -Force Copy-Item (Join-Path $smDir 'winpeshl.ini') (Join-Path $bootmnt 'Windows\System32\winpeshl.ini') -Force Write-Host " staged collector to boot.wim \sm\ + winpeshl.ini" - $setup = if (Test-Path (Join-Path $bootmnt 'sources\setup.exe')) { 'X:\sources\setup.exe' } else { 'X:\setup.exe' } - $cmdline = "$setup /unattend:X:\autounattend.xml" + # Setup\CmdLine is the WinPE setup-image shell launch and is AUTHORITATIVE over + # winpeshl.ini -- point it at the SilverMetal collector so the pre-config UI runs + # FIRST. The collector then launches the LEGACY setup.exe itself (X:\sources\setup.exe, + # preserving the legacy-Setup bypass) with its generated answer file, or falls back to + # the default autounattend.xml on cancel/error. (Pointing Setup\CmdLine straight at + # setup.exe bypassed the collector entirely -- it won over winpeshl.ini.) + $cmdline = "cmd /c X:\sm\Start-Collector.cmd" $hive = Join-Path $bootmnt 'Windows\System32\config\SYSTEM' & reg load 'HKLM\SM_BOOT' $hive | Out-Null try {