Bug 7970 - Client icon isn't changed on upgrade on Windows
Summary: Client icon isn't changed on upgrade on Windows
Status: NEW
Alias: None
Product: ThinLinc
Classification: Unclassified
Component: Client platforms (show other bugs)
Version: trunk
Hardware: PC Unknown
: P2 Normal
Target Milestone: LowPrio
Assignee: Bugzilla mail exporter
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-07-15 14:06 CEST by Pierre Ossman
Modified: 2023-09-11 09:07 CEST (History)
2 users (show)

See Also:
Acceptance Criteria:
* Start menu icon is updated automatically on install * Task bar icon is updated automatically on install * Drop-up menu on right-click the task bar icon is updated automatically on install. * Start menu search results are updated automatically on install * Any other shortcut icons are updated automatically on install


Attachments
I get the same behavior when installing an outdated version of Firefox (62.0) (263.16 KB, image/png)
2023-08-08 08:39 CEST, Frida Flodin
Details

Description Pierre Ossman cendio 2022-07-15 14:06:48 CEST
(moved off bug 7918)

== Pierre Ossman cendio 2022-05-05 10:27:32 CEST ==

Note that it seems Windows has some caching of icons. When installing a client with the new logo, the launcher on the task bar still retains the old icon.

Perhaps we can call something in the installer that flushes this cache?


==  Pierre Ossman cendio 2022-07-15 08:26:45 CEST ==

(In reply to Pierre Ossman from comment #1)
> Note that it seems Windows has some caching of icons. When installing a
> client with the new logo, the launcher on the task bar still retains the old
> icon.
> 
> Perhaps we can call something in the installer that flushes this cache?

I found this:

> Applications that register new handlers of any type must call SHChangeNotify
> with the SHCNE_ASSOCCHANGED flag to instruct the Shell to invalidate the icon
> and thumbnail cache. This will also load new icon and thumbnail handlers that
> have been registered. Note, however, that icon overlay handlers are not
> reloaded.

https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shchangenotify

However, we already call this function from the installer. So something isn't working. We do have this note, though:

> ; Refresh the shell. Note: MSDN says that SHCNF_IDLIST must be specified,
> but the NSIS example does not. 

That comment isn't true any more, as NSIS has updated their example:

https://nsis.sourceforge.io/Refresh_shell_icons


== Pierre Ossman cendio 2022-07-15 09:42:15 CEST ==

Hmm... Odd. I can't reproduce this on the Windows 10 laptop. But I can reproduce it on the Windows 10 desktop in the lab.

One theory is that this has to do with a 32-/64-bit mismatch. Our installer is always 32-bit, and the laptop is 32-bit, whilst the desktop is 64-bit.
Comment 1 Pierre Ossman cendio 2022-07-15 14:12:37 CEST
More digging:

* Windows 11 is also broken, so this is not just a Windows 10 issue

* Using SHCNF_IDLIST doesn't seem to have any effect, anywhere

* The start menu entry seems to update properly, so it's the task bar and other shortcuts that are the issue

* All icons blink at the end of the installation, indicating that something is getting refreshed

* Running "ie4uinit -show" fixes the issue on Windows 10, but does nothing on Windows 11, not even a blink of icons

* Creating a small C program that calls SHChangeNotify() with SHCNE_ASSOCCHANGED fixes other shortcuts on Windows 11, but not the taskbar icon

* Running the above in 32-bit or 64-bit doesn't matter, it works either way, making it very mysterious why NSIS fails when doing the same call
Comment 2 Samuel Mannehed cendio 2023-07-25 10:10:14 CEST
Since we are changing the client icon as of ThinLinc 4.15.0, we need to make an effort here as part of this release.
Comment 3 Frida Flodin cendio 2023-08-01 16:17:30 CEST
Another consequence that might be related to this is that you can't pin the client to the taskbar once you unpinned it, if it was pinned with the old icon before. You have to first restart the client and then pin it again for it to stick. Seen on both Windows 10 and 11.
Comment 4 Frida Flodin cendio 2023-08-08 08:39:18 CEST
Created attachment 1148 [details]
I get the same behavior when installing an outdated version of Firefox (62.0)

Back then, Firefox had another logo where the fox is more detailed and the globe is blue. I then upgraded to the latest version, where the globe should be more purple. As you can see in the screenshot, the taskbar icon is updated, but not the start menu nor the menu you get when you right-click the taskbar icon.

Maybe Windows users are used to issues when applications change logo, and can tolerate a miss match until all caches have been cleared? Perhaps we can opt for best effort on this bug, rather than understanding the cause of the issue and fixing all cases.
Comment 5 Samuel Mannehed cendio 2023-08-08 14:04:04 CEST
The following steps can be taken to reset the windows machine to a state where most icon caches are cleared:

> 1. Start command prompt as administrator
> 2. ie4uinit.exe -show
> 3. taskkill /IM explorer.exe /F
> 4. DEL /A /Q "C:\Users\<USERNAME>\AppData\Local\IconCache.db"
> 5. DEL /A /F /Q "C:\Users\<USERNAME>\AppData\Local\Microsoft\Windows\Explorer\iconcache*"
On windows 10, the start menu search seems to have a separate icon cache. Our items from this cache can be removed like this:

> 6. DEL /A /Q C:\Users\cendio.LAB\AppData\Local\Packages\Microsoft.Windows.Search_cw5n1h2txyewy\LocalState\AppIconCache\100\*thinlinc*
Then reboot:
> 7. shutdown /r /f /t 00
Comment 6 Samuel Mannehed cendio 2023-08-08 14:32:57 CEST
From comment 0 and comment 1 the current state is a bit unclear. To establish a baseline, I took the following steps on both Windows 10 and Windows 11:

1. Installed 4.14.0 client
2. Ran the cache clearing steps from comment 5
3. Upgraded to 4.15.0 beta

This resulted in the following state on both platforms (where ✓ means the icon is properly updated to the new one, and ✗ means it is still incorrectly using the old icon):

 ✓ Alt-Tab icon
 ✓ Start menu ThinLinc folder icons
 ✓ Pinned Start icons
 ✗ Task bar icon (pinned)
 ✓ Task bar icon (after unpin)
 ✗ Task bar right click icon

The only difference between Windows 10 and Windows 11 was:

 ✗ Windows 10: Start menu search icon
 ✓ Windows 11: Start menu search icon
Comment 8 Samuel Mannehed cendio 2023-08-08 16:18:39 CEST
We have decided to drop our efforts here for now. Here's a list of things we tried, without luck:

* Renaming the thinlinc.ico built into the tlclient.exe, see attachment 1151 [details]

* Changing to SHCNF_IDLIST:

>  !define SHCNE_ASSOCCHANGED 0x08000000
> -!define SHCNF_FLUSH        0x1000
> +!define SHCNF_IDLIST 0
>  !macro RefreshShell
> -       ; Refresh the shell. Note: MSDN says that SHCNF_IDLIST must be specified, but the NSIS example does not. 
> -       System::Call "shell32::SHChangeNotify(i,i,i,i) (${SHCNE_ASSOCCHANGED}, ${SHCNF_FLUSH}, 0, 0)"
> +       ; Refresh the shell. 
> +       System::Call "shell32::SHChangeNotify(i,i,i,i) (${SHCNE_ASSOCCHANGED}, ${SHCNF_IDLIST}, 0, 0)"

* Using SetRegView 64:

>  !define SHCNE_ASSOCCHANGED 0x08000000
>  !define SHCNF_FLUSH        0x1000
>  !macro RefreshShell
> +     ${If} ${RunningX64}
> +       SetRegView 64
> +     ${Else}
> +       SetRegView 32
> +     ${EndIf}
>         ; Refresh the shell. Note: MSDN says that SHCNF_IDLIST must be specified, but the NSIS example does not. 
>         System::Call "shell32::SHChangeNotify(i,i,i,i) (${SHCNE_ASSOCCHANGED}, ${SHCNF_FLUSH}, 0, 0)"

* Running SPI_SETICONS:

>  !define SHCNE_ASSOCCHANGED 0x08000000
>  !define SHCNF_FLUSH        0x1000
> +!define SPI_SETICONS 0x0058
>  !macro RefreshShell
>         ; Refresh the shell. Note: MSDN says that SHCNF_IDLIST must be specified, but the NSIS example does not. 
>         System::Call "shell32::SHChangeNotify(i,i,i,i) (${SHCNE_ASSOCCHANGED}, ${SHCNF_FLUSH}, 0, 0)"
> +       System::Call "user32::SystemParametersInfo(i ${SPI_SETICONS},i0,i0,i2)i"

* Resizing the icons back and forth:

>  !macro RefreshShell
>         ; Refresh the shell. Note: MSDN says that SHCNF_IDLIST must be specified, but the NSIS example does not. 
>         System::Call "shell32::SHChangeNotify(i,i,i,i) (${SHCNE_ASSOCCHANGED}, 
> +       ReadRegStr $0 HKCU "Control Panel\Desktop\WindowMetrics" "Shell Icon Size"
> +       IntOp $0 $0 + 1
> +       WriteRegStr HKCU "Control Panel\Desktop\WindowMetrics" "Shell Icon Size" $0
> +       SendMessage 0xffff 0x001A 42 0 /TIMEOUT=100000
> +       IntOp $0 $0 - 1
> +       WriteRegStr HKCU "Control Panel\Desktop\WindowMetrics" "Shell Icon Size" $0
> +       SendMessage 0xffff 0x001A 42 0 /TIMEOUT=100000
>         ; Refresh the shell. Note: MSDN says that SHCNF_IDLIST must be specified, but the NSIS example does not. 
>         System::Call "shell32::SHChangeNotify(i,i,i,i) (${SHCNE_ASSOCCHANGED}, ${SHCNF_FLUSH}, 0, 0)"

* Running "ie4uinit.exe -show" at the end of setup (*):

> @@ -232,6 +240,11 @@ Section "Installer"
>  	WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\tlclient" "NoModify" 1
>  	WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\tlclient" "NoRepair" 1
>  	WriteUninstaller "uninstall.exe"
> +	${DisableX64FSRedirection}
> +	ExecWait '"%WINDIR%\System32\ie4uinit.exe" -show'
> +	${EnableX64FSRedirection}
> +
>  SectionEnd
>  
>  !define TargetDir $INSTDIR

* Running WM_SETICON:

> @@ -270,6 +285,14 @@ Section "Client Shortcuts"
>  	CreateShortCut "$SMPROGRAMS\ThinLinc\Loop ThinLinc Client.lnk" "$INSTDIR\tlclient.exe" "--loop" "$INSTDIR\tlclient.exe" 0
>  	WriteINIStr "$SMPROGRAMS\ThinLinc\desktop.ini" LocalizedFileNames "Loop ThinLinc Client.lnk" @"$INSTDIR\tlclient.exe",-10004
>  
> +	; Change both icons to the same icon handle.
> +	System::Call "SendMessage(hwnd, WM_SETICON, ICON_SMALL, LoadIcon( GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1) ))"
> +	System::Call "SendMessage(hwnd, WM_SETICON, ICON_BIG, LoadIcon( GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1) ))"
> +
> +	; This will ensure that the application icon gets changed too.
> +	System::Call "SendMessage(GetHandle(), WM_SETICON, ICON_SMALL, LoadIcon( GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1) ))"
> +	System::Call "SendMessage(GetHandle(), WM_SETICON, ICON_BIG, LoadIcon( GetModuleHandle(NULL), MAKEINTRESOURCE(IDI_ICON1) ))"
> +
>  	; File association and mime type
>  	WriteRegStr HKCR ".tlclient" "" "ThinLinc.Client"
>  	WriteRegStr HKCR "ThinLinc.Client" "" "ThinLinc Client Configuration"

(*) Note that our installer doesn't seem to run ie4uinit.exe properly, I could not make it work. This thread [1] hints that it might be an issue with the fact that we have a 32-bit installer. Running ie4uinit.exe manually works well on Windows 10 (and fixes the pinned task bar icon, and any shortcuts on the desktop).

[1] https://stackoverflow.com/questions/44904898/inno-setup-unable-to-find-and-execute-ie4uinit-exe-on-x64

This seems to be a very common issue. Many developers are facing this, and it seems both Firefox and Visual Studio Code also took the decision to ignore this issue. Hopefully, the problem is temporary for users, and we hope that the icon caches are refreshed eventually.
Comment 9 Samuel Mannehed cendio 2023-08-08 16:32:06 CEST
Additionally, we also tested adding a call to SHChangeNotify with SHCNE_UPDATEITEM. But that was also unsuccessful:

>  !define SHCNE_ASSOCCHANGED 0x08000000
>  !define SHCNF_FLUSH        0x1000
> +!define SHCNE_UPDATEITEM 0x00002000
> +!define SHCNF_PATH 5
>  !macro RefreshShell
>         ; Refresh the shell. Note: MSDN says that SHCNF_IDLIST must be specified, but the NSIS example does not. 
>         System::Call "shell32::SHChangeNotify(i,i,i,i) (${SHCNE_ASSOCCHANGED}, ${SHCNF_FLUSH}, 0, 0)"
> +    System::Call "shell32::SHChangeNotify(${SHCNE_UPDATEITEM}, ${SHCNF_PATH}, 'ThinLinc Client', nil)"
>  !macroend

With that, we will not continue working on this for now. Removing from the 4.15.0 milestone.
Comment 10 Pierre Ossman cendio 2023-09-11 09:07:37 CEST
The cache seems to resolve itself after a day or two. I upgraded from 4.14.0 to 4.15.0 on a Windows 10 machine at home, and it switched to the correct icon later the same week.

Note You need to log in before you can comment on or make changes to this bug.