From df8781f204084e4a83047df00e4bb2e07346540b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ji=C5=99=C3=AD=20Pol=C3=A1=C5=A1ek?= Date: Thu, 22 Jan 2026 19:25:24 +0100 Subject: [PATCH] CmdPal: Improve loading of application icons - part 1 (#44938) ## Summary of the Pull Request This PR improves loading of application icons: - Fixes loading of icons from internet shortcuts ## Pictures? Pictures! image ## PR Checklist - [x] Closes: #44819 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx ## Detailed Description of the Pull Request / Additional comments ## Validation Steps Performed --- .../Microsoft.CmdPal.Ext.Apps/AppListItem.cs | 60 +++++++++++-------- .../Programs/Win32Program.cs | 3 - 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/AppListItem.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/AppListItem.cs index 5689b70698..176fae30d2 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/AppListItem.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/AppListItem.cs @@ -98,18 +98,16 @@ public sealed partial class AppListItem : ListItem } else { - try + // do nothing if we fail to load an icon. + // Logging it would be too NOISY, there's really no need. + if (!string.IsNullOrEmpty(_app.IcoPath)) { - var stream = await ThumbnailHelper.GetThumbnail(_app.ExePath, true); - if (stream is not null) - { - heroImage = IconInfo.FromStream(stream); - } + heroImage = await TryLoadThumbnail(_app.IcoPath, jumbo: true, logOnFailure: false); } - catch (Exception) + + if (heroImage == null && !string.IsNullOrEmpty(_app.ExePath)) { - // do nothing if we fail to load an icon. - // Logging it would be too NOISY, there's really no need. + heroImage = await TryLoadThumbnail(_app.ExePath, jumbo: true, logOnFailure: false); } } @@ -132,26 +130,19 @@ public sealed partial class AppListItem : ListItem if (useThumbnails) { - try + if (!string.IsNullOrEmpty(_app.IcoPath)) { - var stream = await ThumbnailHelper.GetThumbnail(_app.ExePath); - if (stream is not null) - { - icon = IconInfo.FromStream(stream); - } - } - catch (Exception ex) - { - Logger.LogDebug($"Failed to load icon for {AppIdentifier}:\n{ex}"); + icon = await TryLoadThumbnail(_app.IcoPath, jumbo: false, logOnFailure: true); } - icon = icon ?? new IconInfo(_app.IcoPath); - } - else - { - icon = new IconInfo(_app.IcoPath); + if (icon == null && !string.IsNullOrEmpty(_app.ExePath)) + { + icon = await TryLoadThumbnail(_app.ExePath, jumbo: false, logOnFailure: true); + } } + icon ??= new IconInfo(_app.IcoPath); + return icon; } @@ -183,4 +174,25 @@ public sealed partial class AppListItem : ListItem return newCommands.ToArray(); } + + private async Task TryLoadThumbnail(string path, bool jumbo, bool logOnFailure) + { + try + { + var stream = await ThumbnailHelper.GetThumbnail(path, jumbo); + if (stream is not null) + { + return IconInfo.FromStream(stream); + } + } + catch (Exception ex) + { + if (logOnFailure) + { + Logger.LogDebug($"Failed to load icon {path} for {AppIdentifier}:\n{ex}"); + } + } + + return null; + } } diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/Programs/Win32Program.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/Programs/Win32Program.cs index fda8e2c697..1de01b408e 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/Programs/Win32Program.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Apps/Programs/Win32Program.cs @@ -1052,9 +1052,6 @@ public class Win32Program : IProgram app.FullPath) : app.IcoPath; - icoPath = icoPath.EndsWith(".lnk", System.StringComparison.InvariantCultureIgnoreCase) ? - app.FullPath : - icoPath; return new AppItem() { Name = app.Name,