From 7580797b9e9fa80bebf129a01350cc15403eb397 Mon Sep 17 00:00:00 2001 From: "Yu Leng (from Dev Box)" Date: Sat, 7 Feb 2026 21:05:34 +0800 Subject: [PATCH] Fix ImageResizer build artifacts and installer issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Migrated ESRP signing config to reference only WinUI3Apps paths for ImageResizer files, avoiding root-level artifacts. Added a workaround in generateAllFileComponents.ps1 to strip incomplete ImageResizer build outputs caused by Exe→WinExe ProjectReference. Updated migration notes to document removal of satellite assembly references and explain the root cause and temporary fix for phantom build artifacts. Recommend refactoring to use a shared Library project for CLI dependencies. --- .pipelines/ESRPSigning_core.json | 6 +++--- .../generateAllFileComponents.ps1 | 18 +++++++++++++++++ src/modules/imageresizer/MIGRATION-NOTES.md | 20 +++++++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/.pipelines/ESRPSigning_core.json b/.pipelines/ESRPSigning_core.json index 00ab683085..2b819a278b 100644 --- a/.pipelines/ESRPSigning_core.json +++ b/.pipelines/ESRPSigning_core.json @@ -138,9 +138,9 @@ "WinUI3Apps\\PowerToys.ImageResizer.dll", "WinUI3Apps\\PowerToys.ImageResizerCLI.exe", "WinUI3Apps\\PowerToys.ImageResizerCLI.dll", - "PowerToys.ImageResizerExt.dll", - "PowerToys.ImageResizerContextMenu.dll", - "ImageResizerContextMenuPackage.msix", + "WinUI3Apps\\PowerToys.ImageResizerExt.dll", + "WinUI3Apps\\PowerToys.ImageResizerContextMenu.dll", + "WinUI3Apps\\ImageResizerContextMenuPackage.msix", "PowerToys.LightSwitchModuleInterface.dll", "LightSwitchService\\PowerToys.LightSwitchService.exe", diff --git a/installer/PowerToysSetupVNext/generateAllFileComponents.ps1 b/installer/PowerToysSetupVNext/generateAllFileComponents.ps1 index 6724d95170..2325d71140 100644 --- a/installer/PowerToysSetupVNext/generateAllFileComponents.ps1 +++ b/installer/PowerToysSetupVNext/generateAllFileComponents.ps1 @@ -131,7 +131,25 @@ if ($platform -ceq "arm64") { } #BaseApplications +# WORKAROUND: Exclude ImageResizer files that leak into the root output directory. +# ImageResizerCLI (Exe, SelfContained) has a ProjectReference to ImageResizerUI (WinExe, SelfContained). +# MSBuild copies the referenced WinExe's apphost (.exe, .deps.json, .runtimeconfig.json) to the root +# output directory as a side effect. These files are incomplete (missing the managed .dll) and should +# not be included in the installer. The complete ImageResizer files are in WinUI3Apps/ and are handled +# by WinUI3ApplicationsFiles. TODO: Refactor ImageResizer to use a shared Library project instead. Generate-FileList -fileDepsJson "" -fileListName BaseApplicationsFiles -wxsFilePath $PSScriptRoot\BaseApplications.wxs -depsPath "$PSScriptRoot..\..\..\$platform\Release" + +# Remove leaked ImageResizer artifacts from BaseApplications +$baseAppWxsPath = "$PSScriptRoot\BaseApplications.wxs" +$baseAppWxs = Get-Content $baseAppWxsPath -Raw +$baseAppWxs = $baseAppWxs -replace 'PowerToys\.ImageResizer\.exe;?', '' +$baseAppWxs = $baseAppWxs -replace 'PowerToys\.ImageResizer\.deps\.json;?', '' +$baseAppWxs = $baseAppWxs -replace 'PowerToys\.ImageResizer\.runtimeconfig\.json;?', '' +# Clean up trailing/double semicolons left after removal +$baseAppWxs = $baseAppWxs -replace ';;+', ';' +$baseAppWxs = $baseAppWxs -replace '=;', '=' +$baseAppWxs = $baseAppWxs -replace ';"', '"' +Set-Content -Path $baseAppWxsPath -Value $baseAppWxs Generate-FileComponents -fileListName "BaseApplicationsFiles" -wxsFilePath $PSScriptRoot\BaseApplications.wxs #WinUI3Applications diff --git a/src/modules/imageresizer/MIGRATION-NOTES.md b/src/modules/imageresizer/MIGRATION-NOTES.md index 8c52dc90d0..23c1ab7139 100644 --- a/src/modules/imageresizer/MIGRATION-NOTES.md +++ b/src/modules/imageresizer/MIGRATION-NOTES.md @@ -31,3 +31,23 @@ The ImageResizer module's core image processing was migrated from WPF (`System.W ### Pixel-Level Differences WinRT's `BitmapInterpolationMode.Fant` may produce slightly different pixel values compared to WPF's internal scaling algorithm. Both are high-quality interpolation methods, but they are not guaranteed to produce bit-identical output. This is expected and does not affect visual quality. + +## Installer / Build Pipeline Issues + +### Satellite Assembly References Removed from Resources.wxs + +**Problem**: After migrating to WinUI 3, the WiX installer failed with `WIX0103` errors — it could not find `PowerToys.ImageResizer.resources.dll` satellite assemblies in `WinUI3Apps/{locale}/` directories. + +**Root cause**: WPF uses `.resx` files which compile into satellite assemblies (`.resources.dll`). WinUI 3 uses `.resw` files which compile into `.pri` files. The installer's `Resources.wxs` still referenced the old satellite assembly pattern. + +**Fix**: Removed the ImageResizer satellite assembly component, `WinUI3AppsInstallFolder` from the `ParentDirectory` foreach loop, and the corresponding `RemoveFolder` entry from `Resources.wxs`. + +### Phantom Root-Level Build Artifacts + +**Problem**: `PowerToys.ImageResizer.exe`, `.deps.json`, and `.runtimeconfig.json` appear in the root output directory (`x64/Release/`) even though the project's `OutputPath` is `WinUI3Apps/`. This caused the installer to include an incomplete, non-functional copy (missing the managed `.dll`) and the ESRP signing check to fail. + +**Root cause**: `ImageResizerCLI` (`OutputType=Exe`, `SelfContained=true`) has a `` to `ImageResizerUI` (`OutputType=WinExe`, `SelfContained=true`). When MSBuild processes an Exe→WinExe dependency between two self-contained projects, it copies the referenced project's apphost (`.exe`) and runtime config files to the root output directory as a side effect. This is the **only** Exe→WinExe `ProjectReference` in the entire PowerToys codebase — other CLI tools (e.g., FancyZonesCLI) correctly reference a shared Library project instead. + +**Temporary fix**: `generateAllFileComponents.ps1` strips the leaked ImageResizer files from the `BaseApplicationsFiles` list after generation. The signing config (`ESRPSigning_core.json`) only references `WinUI3Apps\\` paths. + +**TODO**: Refactor the dependency — extract shared CLI logic from `ImageResizerUI` (`ui/Cli/` folder) into a separate Library project, so `ImageResizerCLI` references a Library instead of a WinExe. This follows the pattern used by `FancyZonesCLI` → `FancyZonesEditorCommon`.