From 0d22662c382dcc7002b5b5114f02efac4baac818 Mon Sep 17 00:00:00 2001
From: art804 <7828385+art804@users.noreply.github.com>
Date: Mon, 9 Nov 2026 13:45:40 +1300
Subject: [PATCH] Windows: shortcuts take pdfcraft.exe's icon, so a taskbar pin
keeps it (#6184)
---
packaging/windows/pdfcraft.wxs | 9 ++++++---
packaging/windows/test-msi.ps1 | 7 ++++---
2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/packaging/windows/pdfcraft.wxs b/packaging/windows/pdfcraft.wxs
index 44f6012ba0..f11ca83a6f 100644
--- a/packaging/windows/pdfcraft.wxs
+++ b/packaging/windows/pdfcraft.wxs
@@ -133,14 +133,17 @@
ones point at a Windows Installer descriptor rather than the program, which Windows can't
use as a file handler (#107), and 0.2.1's advertised one went missing from the Start menu
(#143). Each has its own component with an HKLM key path, so Windows Installer removes it
- on uninstall; in this per-machine package both folders are the all-users ones. -->
+ on uninstall; in this per-machine package both folders are the all-users ones. They take
+ their icon from pdfcraft.exe, not the Icon table: Windows Installer keeps that copy under
+ the ProductCode, which every release changes, so a taskbar pin made from a shortcut that
+ named it shows a blank icon once an update removes the old release. -->
-
+
diff --git a/packaging/windows/test-msi.ps1 b/packaging/windows/test-msi.ps1
index 5dc4152d8f..16fbebe484 100644
--- a/packaging/windows/test-msi.ps1
+++ b/packaging/windows/test-msi.ps1
@@ -73,15 +73,16 @@ $status = Read-Row 'SELECT `Text` FROM `Control` WHERE `Dialog_` = ''InstallProg
Assert-Equal $status[0] 'Please wait while setup completes.' 'Persistent progress message'
Assert-NoRow 'SELECT `Event` FROM `EventMapping` WHERE `Dialog_` = ''InstallProgress'' AND `Control_` = ''Status''' 'progress text subscription'
-# Plain (non-advertised) shortcuts to pdfcraft.exe, each in its own component; the desktop one is
-# gated by INSTALLDESKTOPSHORTCUT, which is secure so the UI choice reaches the
+# Plain (non-advertised) shortcuts to pdfcraft.exe, each in its own component and with no Icon
+# table entry, so the shell takes the exe's own icon and a pin keeps it across updates. The
+# desktop one is gated by INSTALLDESKTOPSHORTCUT, which is secure so the UI choice reaches the
# elevated install.
foreach ($entry in @(@('StartMenuShortcut', 'ProgramMenuFolder', 'PdfcraftStartMenuShortcut', ''),
@('DesktopShortcut', 'DesktopFolder', 'PdfcraftDesktopShortcut', 'INSTALLDESKTOPSHORTCUT = 1'))) {
$row = Read-Row ('SELECT `Directory_`, `Target`, `Icon_`, `WkDir`, `Component_` FROM `Shortcut` WHERE `Shortcut` = ''' + $entry[0] + '''') 5
Assert-Equal $row[0] $entry[1] "$($entry[0]) directory"
Assert-Equal $row[1] '[#PdfcraftExe]' "$($entry[0]) target"
- Assert-Equal $row[2] 'PdfcraftIcon.ico' "$($entry[0]) icon"
+ Assert-Equal $row[2] '' "$($entry[0]) icon"
Assert-Equal $row[3] 'INSTALLFOLDER' "$($entry[0]) working directory"
Assert-Equal $row[4] $entry[2] "$($entry[0]) component"
$component = Read-Row ('SELECT `Directory_`, `Condition` FROM `Component` WHERE `Component` = ''' + $entry[2] + '''') 2