From 846cc65d8e01f6b1f4c765c7641d169db2988781 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 21 Sep 2025 04:49:51 +0000 Subject: [PATCH 01/13] Bump Svg.Skia from 3.0.6 to 3.2.1 --- updated-dependencies: - dependency-name: Svg.Skia dependency-version: 3.2.1 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .../Flow.Launcher.Plugin.BrowserBookmark.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj index e3233f73d..6f058ea24 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj @@ -106,7 +106,7 @@ - + From bfd10f690324af0a30b7767817e04da8c4db3b47 Mon Sep 17 00:00:00 2001 From: dcog989 Date: Mon, 22 Sep 2025 13:37:22 +0100 Subject: [PATCH 02/13] Crash when opening non-existent file --- Flow.Launcher/PublicAPIInstance.cs | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index 6a8ee40f9..731c329e2 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -412,6 +412,14 @@ namespace Flow.Launcher private void OpenUri(Uri uri, bool? inPrivate = null, bool forceBrowser = false) { + if (uri.IsFile) + { + if (!File.Exists(uri.LocalPath) && !Directory.Exists(uri.LocalPath)) + { + ShowMsgError(GetTranslation("errorTitle"), $"File or directory not found: {uri.LocalPath}"); + return; + } + } if (forceBrowser || uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps) { var browserInfo = _settings.CustomBrowser; @@ -441,13 +449,19 @@ namespace Flow.Launcher } else { - Process.Start(new ProcessStartInfo() + try { - FileName = uri.AbsoluteUri, - UseShellExecute = true - })?.Dispose(); - - return; + Process.Start(new ProcessStartInfo() + { + FileName = uri.AbsoluteUri, + UseShellExecute = true + })?.Dispose(); + } + catch (Exception e) + { + LogException(ClassName, $"Failed to open: {uri.AbsoluteUri}", e); + ShowMsgError(GetTranslation("errorTitle"), e.Message); + } } } From 71b8144c3c428f4ffe2ebbbfc3544a0bf5afbc69 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Mon, 22 Sep 2025 20:55:36 +0800 Subject: [PATCH 03/13] Add translations & Improve code quality --- Flow.Launcher/Languages/en.xaml | 1 + Flow.Launcher/PublicAPIInstance.cs | 12 +++++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index 626fe1385..561bb277e 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -590,6 +590,7 @@ Error An error occurred while opening the folder. {0} An error occurred while opening the URL in the browser. Please check your Default Web Browser configuration in the General section of the settings window + File or directory not found: {0} Please wait... diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index 731c329e2..cbd793dc8 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Specialized; @@ -412,14 +412,12 @@ namespace Flow.Launcher private void OpenUri(Uri uri, bool? inPrivate = null, bool forceBrowser = false) { - if (uri.IsFile) + if (uri.IsFile && !File.Exists(uri.LocalPath) && !Directory.Exists(uri.LocalPath)) { - if (!File.Exists(uri.LocalPath) && !Directory.Exists(uri.LocalPath)) - { - ShowMsgError(GetTranslation("errorTitle"), $"File or directory not found: {uri.LocalPath}"); - return; - } + ShowMsgError(GetTranslation("errorTitle"), string.Format(GetTranslation("fileNotFoundError"), uri.LocalPath)); + return; } + if (forceBrowser || uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps) { var browserInfo = _settings.CustomBrowser; From 763fee0c1400ef3cf3b1cfb49cd0e54ec5c0ce7b Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Mon, 22 Sep 2025 20:58:22 +0800 Subject: [PATCH 04/13] Add new helper method & Improve code quality --- Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs | 10 ++++++++++ Flow.Launcher/PublicAPIInstance.cs | 11 +++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs index 6c506cfc0..3af57f00d 100644 --- a/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs +++ b/Flow.Launcher.Plugin/SharedCommands/FilesFolders.cs @@ -150,6 +150,16 @@ namespace Flow.Launcher.Plugin.SharedCommands return File.Exists(filePath); } + /// + /// Checks if a file or directory exists + /// + /// + /// + public static bool FileOrLocationExists(this string path) + { + return LocationExists(path) || FileExists(path); + } + /// /// Open a directory window (using the OS's default handler, usually explorer) /// diff --git a/Flow.Launcher/PublicAPIInstance.cs b/Flow.Launcher/PublicAPIInstance.cs index cbd793dc8..b4c3aa92b 100644 --- a/Flow.Launcher/PublicAPIInstance.cs +++ b/Flow.Launcher/PublicAPIInstance.cs @@ -74,7 +74,6 @@ namespace Flow.Launcher _mainVM.ChangeQueryText(query, requery); } - [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "VSTHRD100:Avoid async void methods", Justification = "")] public void RestartApp() { _mainVM.Hide(); @@ -179,7 +178,7 @@ namespace Flow.Launcher Clipboard.SetFileDropList(paths); }); - + if (exception == null) { if (showDefaultNotification) @@ -218,7 +217,7 @@ namespace Flow.Launcher { LogException(nameof(PublicAPIInstance), "Failed to copy text to clipboard", exception); ShowMsgError(GetTranslation("failedToCopy")); - } + } } } @@ -327,7 +326,7 @@ namespace Flow.Launcher ((PluginJsonStorage)_pluginJsonStorages[type]).Save(); } - + public void OpenDirectory(string directoryPath, string fileNameOrFilePath = null) { try @@ -412,7 +411,7 @@ namespace Flow.Launcher private void OpenUri(Uri uri, bool? inPrivate = null, bool forceBrowser = false) { - if (uri.IsFile && !File.Exists(uri.LocalPath) && !Directory.Exists(uri.LocalPath)) + if (uri.IsFile && !FilesFolders.FileOrLocationExists(uri.LocalPath)) { ShowMsgError(GetTranslation("errorTitle"), string.Format(GetTranslation("fileNotFoundError"), uri.LocalPath)); return; @@ -493,7 +492,7 @@ namespace Flow.Launcher OpenUri(appUri); } - public void ToggleGameMode() + public void ToggleGameMode() { _mainVM.ToggleGameMode(); } From fbc88bb4cdea088751578e5c749d2a20c499a722 Mon Sep 17 00:00:00 2001 From: Spencer Stream Date: Mon, 22 Sep 2025 19:40:01 -0500 Subject: [PATCH 05/13] Add ini-parser package to Infrastructure project --- Flow.Launcher.Core/packages.lock.json | 8 +++++++- .../Flow.Launcher.Infrastructure.csproj | 1 + Flow.Launcher.Infrastructure/packages.lock.json | 6 ++++++ Flow.Launcher/packages.lock.json | 8 +++++++- 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Core/packages.lock.json b/Flow.Launcher.Core/packages.lock.json index b7a00d94d..373cdcd15 100644 --- a/Flow.Launcher.Core/packages.lock.json +++ b/Flow.Launcher.Core/packages.lock.json @@ -83,6 +83,11 @@ "resolved": "1.0.0", "contentHash": "nwbZAYd+DblXAIzlnwDSnl0CiCm8jWLfHSYnoN4wYhtIav6AegB3+T/vKzLbU2IZlPB8Bvl8U3NXpx3eaz+N5w==" }, + "ini-parser": { + "type": "Transitive", + "resolved": "2.5.2", + "contentHash": "hp3gKmC/14+6eKLgv7Jd1Z7OV86lO+tNfOXr/stQbwmRhdQuXVSvrRAuAe7G5+lwhkov0XkqZ8/bn1PYWMx6eg==" + }, "InputSimulator": { "type": "Transitive", "resolved": "1.0.4", @@ -263,7 +268,8 @@ "NLog.OutputDebugString": "[6.0.4, )", "SharpVectors.Wpf": "[1.8.5, )", "System.Drawing.Common": "[7.0.0, )", - "ToolGood.Words.Pinyin": "[3.1.0.3, )" + "ToolGood.Words.Pinyin": "[3.1.0.3, )", + "ini-parser": "[2.5.2, )" } }, "flow.launcher.plugin": { diff --git a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj index 5b4eaf893..d0c9ebdda 100644 --- a/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj +++ b/Flow.Launcher.Infrastructure/Flow.Launcher.Infrastructure.csproj @@ -60,6 +60,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/Flow.Launcher.Infrastructure/packages.lock.json b/Flow.Launcher.Infrastructure/packages.lock.json index 47c94d5f6..a1aea7f88 100644 --- a/Flow.Launcher.Infrastructure/packages.lock.json +++ b/Flow.Launcher.Infrastructure/packages.lock.json @@ -29,6 +29,12 @@ "resolved": "6.9.3", "contentHash": "1CUGgFdyECDKgi5HaUBhdv6k+VG9Iy4OCforGfHyar3xQXAJypZkzymgKtWj/4SPd6nSG0Qi7NH71qHrDSZLaA==" }, + "ini-parser": { + "type": "Direct", + "requested": "[2.5.2, )", + "resolved": "2.5.2", + "contentHash": "hp3gKmC/14+6eKLgv7Jd1Z7OV86lO+tNfOXr/stQbwmRhdQuXVSvrRAuAe7G5+lwhkov0XkqZ8/bn1PYWMx6eg==" + }, "InputSimulator": { "type": "Direct", "requested": "[1.0.4, )", diff --git a/Flow.Launcher/packages.lock.json b/Flow.Launcher/packages.lock.json index c90db6b0c..4af9894ce 100644 --- a/Flow.Launcher/packages.lock.json +++ b/Flow.Launcher/packages.lock.json @@ -204,6 +204,11 @@ "resolved": "1.11.42", "contentHash": "LDc1bEfF14EY2DZzak4xvzWvbpNXK3vi1u0KQbBpLUN4+cx/VrvXhgCAMSJhSU5vz0oMfW9JZIR20vj/PkDHPA==" }, + "ini-parser": { + "type": "Transitive", + "resolved": "2.5.2", + "contentHash": "hp3gKmC/14+6eKLgv7Jd1Z7OV86lO+tNfOXr/stQbwmRhdQuXVSvrRAuAe7G5+lwhkov0XkqZ8/bn1PYWMx6eg==" + }, "InputSimulator": { "type": "Transitive", "resolved": "1.0.4", @@ -863,7 +868,8 @@ "NLog.OutputDebugString": "[6.0.4, )", "SharpVectors.Wpf": "[1.8.5, )", "System.Drawing.Common": "[7.0.0, )", - "ToolGood.Words.Pinyin": "[3.1.0.3, )" + "ToolGood.Words.Pinyin": "[3.1.0.3, )", + "ini-parser": "[2.5.2, )" } }, "flow.launcher.plugin": { From 90c73e5e3df07bd1fcee73d9e423017456d541ab Mon Sep 17 00:00:00 2001 From: Spencer Stream Date: Mon, 22 Sep 2025 19:40:58 -0500 Subject: [PATCH 06/13] Support .url file icons --- .../Image/ThumbnailReader.cs | 44 +++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs index 4ce0df026..dbe6a694b 100644 --- a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs +++ b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs @@ -1,13 +1,14 @@ using System; -using System.Runtime.InteropServices; using System.IO; +using System.Runtime.InteropServices; using System.Windows; using System.Windows.Interop; using System.Windows.Media.Imaging; +using IniParser; using Windows.Win32; using Windows.Win32.Foundation; -using Windows.Win32.UI.Shell; using Windows.Win32.Graphics.Gdi; +using Windows.Win32.UI.Shell; namespace Flow.Launcher.Infrastructure.Image { @@ -35,9 +36,21 @@ namespace Flow.Launcher.Infrastructure.Image private static readonly HRESULT S_PATHNOTFOUND = (HRESULT)0x8004B205; + private const string UrlExtension = ".url"; + public static BitmapSource GetThumbnail(string fileName, int width, int height, ThumbnailOptions options) { - HBITMAP hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options); + HBITMAP hBitmap; + + var extension = Path.GetExtension(fileName)?.ToLowerInvariant(); + if (extension is UrlExtension) + { + hBitmap = GetHBitmapForUrlFile(fileName, width, height, options); + } + else + { + hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options); + } try { @@ -108,5 +121,30 @@ namespace Flow.Launcher.Infrastructure.Image return hBitmap; } + + private static unsafe HBITMAP GetHBitmapForUrlFile(string fileName, int width, int height, ThumbnailOptions options) + { + HBITMAP hBitmap; + + try + { + var parser = new FileIniDataParser(); + var data = parser.ReadFile(fileName); + var urlSection = data["InternetShortcut"]; + + var iconPath = urlSection?["IconFile"]; + if (string.IsNullOrEmpty(iconPath)) + { + throw new FileNotFoundException(); + } + hBitmap = GetHBitmap(Path.GetFullPath(iconPath), width, height, options); + } + catch + { + hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options); + } + + return hBitmap; + } } } From c293a273ca5b7839d715e7a94cd436c4a01ab7c1 Mon Sep 17 00:00:00 2001 From: Spencer Stream Date: Mon, 22 Sep 2025 21:53:54 -0500 Subject: [PATCH 07/13] Fix nitpick on extension string comparison --- Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs index dbe6a694b..68940ff6a 100644 --- a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs +++ b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs @@ -42,8 +42,8 @@ namespace Flow.Launcher.Infrastructure.Image { HBITMAP hBitmap; - var extension = Path.GetExtension(fileName)?.ToLowerInvariant(); - if (extension is UrlExtension) + var extension = Path.GetExtension(fileName); + if (string.Equals(extension, UrlExtension, StringComparison.OrdinalIgnoreCase)) { hBitmap = GetHBitmapForUrlFile(fileName, width, height, options); } From 130033cf4b8f302537c969fba4a4529b2b93f0d2 Mon Sep 17 00:00:00 2001 From: Jack Ye Date: Tue, 23 Sep 2025 12:22:46 +0800 Subject: [PATCH 08/13] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs index 68940ff6a..c942488c4 100644 --- a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs +++ b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs @@ -135,7 +135,7 @@ namespace Flow.Launcher.Infrastructure.Image var iconPath = urlSection?["IconFile"]; if (string.IsNullOrEmpty(iconPath)) { - throw new FileNotFoundException(); + throw new FileNotFoundException("Icon file not specified in Internet shortcut (.url) file."); } hBitmap = GetHBitmap(Path.GetFullPath(iconPath), width, height, options); } From 49d5cd36df9bb788e1899cfbe61dbd60fa0b17c1 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Tue, 23 Sep 2025 12:24:44 +0800 Subject: [PATCH 09/13] Catch exception --- Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs index c942488c4..9f38a64df 100644 --- a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs +++ b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs @@ -141,7 +141,15 @@ namespace Flow.Launcher.Infrastructure.Image } catch { - hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options); + try + { + hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options); + } + catch (System.Exception ex) + { + // Handle other exceptions + throw new InvalidOperationException("Failed to get thumbnail", ex); + } } return hBitmap; From 3bd6906c800932c944bd037fa20ad8e0474645b0 Mon Sep 17 00:00:00 2001 From: Spencer Stream Date: Tue, 23 Sep 2025 07:19:39 -0500 Subject: [PATCH 10/13] Validate iconPath exists --- Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs index 9f38a64df..011f01ca5 100644 --- a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs +++ b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs @@ -133,8 +133,9 @@ namespace Flow.Launcher.Infrastructure.Image var urlSection = data["InternetShortcut"]; var iconPath = urlSection?["IconFile"]; - if (string.IsNullOrEmpty(iconPath)) + if (!File.Exists(iconPath)) { + // If the IconFile is missing, throw exception to fallback to the default icon throw new FileNotFoundException("Icon file not specified in Internet shortcut (.url) file."); } hBitmap = GetHBitmap(Path.GetFullPath(iconPath), width, height, options); From 9b2d36b78a79ba6493555eda12ef1595c732a5d6 Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Tue, 23 Sep 2025 20:48:41 +0800 Subject: [PATCH 11/13] Revert "Catch exception" This reverts commit 49d5cd36df9bb788e1899cfbe61dbd60fa0b17c1. --- Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs index 9f38a64df..c942488c4 100644 --- a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs +++ b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs @@ -141,15 +141,7 @@ namespace Flow.Launcher.Infrastructure.Image } catch { - try - { - hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options); - } - catch (System.Exception ex) - { - // Handle other exceptions - throw new InvalidOperationException("Failed to get thumbnail", ex); - } + hBitmap = GetHBitmap(Path.GetFullPath(fileName), width, height, options); } return hBitmap; From ba7de5d33d4b8ae6a35f587ebd2ae022267a665a Mon Sep 17 00:00:00 2001 From: Jack251970 <1160210343@qq.com> Date: Tue, 23 Sep 2025 21:39:42 +0800 Subject: [PATCH 12/13] Add documents --- .../Image/ThumbnailReader.cs | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs index 3b6f66bca..86f757eb8 100644 --- a/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs +++ b/Flow.Launcher.Infrastructure/Image/ThumbnailReader.cs @@ -38,6 +38,17 @@ namespace Flow.Launcher.Infrastructure.Image private const string UrlExtension = ".url"; + /// + /// Obtains a BitmapSource thumbnail for the specified file. + /// + /// + /// If the file is a Windows URL shortcut (".url"), the method attempts to resolve the shortcut's icon and use that for the thumbnail; otherwise it requests a thumbnail for the file path. The native HBITMAP used to create the BitmapSource is always released to avoid native memory leaks. + /// + /// Path to the file (can be a regular file or a ".url" shortcut). + /// Requested thumbnail width in pixels. + /// Requested thumbnail height in pixels. + /// Thumbnail extraction options (flags) controlling fallback and caching behavior. + /// A BitmapSource representing the requested thumbnail. public static BitmapSource GetThumbnail(string fileName, int width, int height, ThumbnailOptions options) { HBITMAP hBitmap; @@ -63,6 +74,21 @@ namespace Flow.Launcher.Infrastructure.Image } } + /// + /// Obtains a native HBITMAP for the specified file at the requested size using the Windows Shell image factory. + /// + /// + /// If is and thumbnail extraction fails + /// due to extraction errors or a missing path, the method falls back to requesting an icon (). + /// The returned HBITMAP is a raw GDI handle; the caller is responsible for releasing it (e.g., via DeleteObject) to avoid native memory leaks. + /// + /// Path to the file to thumbnail. + /// Requested thumbnail width in pixels. + /// Requested thumbnail height in pixels. + /// Thumbnail request flags that control behavior (e.g., ThumbnailOnly, IconOnly). + /// An HBITMAP handle containing the image. Caller must free the handle when finished. + /// If creating the shell item fails (HRESULT returned by SHCreateItemFromParsingName). + /// If the shell item does not expose IShellItemImageFactory or if an unexpected error occurs while obtaining the image. private static unsafe HBITMAP GetHBitmap(string fileName, int width, int height, ThumbnailOptions options) { var retCode = PInvoke.SHCreateItemFromParsingName( @@ -122,6 +148,19 @@ namespace Flow.Launcher.Infrastructure.Image return hBitmap; } + /// + /// Obtains an HBITMAP for a Windows .url shortcut by resolving its IconFile entry and delegating to GetHBitmap. + /// + /// + /// The method parses the .url file as an INI, looks in the "InternetShortcut" section for the "IconFile" entry, + /// and requests a bitmap for that icon path. If no IconFile is present or any error occurs while reading or + /// resolving the icon, it falls back to requesting a thumbnail for the .url file itself. + /// + /// Path to the .url shortcut file. + /// Requested thumbnail width (pixels). + /// Requested thumbnail height (pixels). + /// ThumbnailOptions flags controlling extraction behavior. + /// An HBITMAP containing the requested image; callers are responsible for freeing the native handle. private static unsafe HBITMAP GetHBitmapForUrlFile(string fileName, int width, int height, ThumbnailOptions options) { HBITMAP hBitmap; From a76e2fea7f4febf7aff1c258ba5997ea49ba996a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Sep 2025 22:06:58 +0000 Subject: [PATCH 13/13] Bump SkiaSharp from 3.119.0 to 3.119.1 --- updated-dependencies: - dependency-name: SkiaSharp dependency-version: 3.119.1 dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .../Flow.Launcher.Plugin.BrowserBookmark.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj index 8a9162e62..5116642ca 100644 --- a/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj +++ b/Plugins/Flow.Launcher.Plugin.BrowserBookmark/Flow.Launcher.Plugin.BrowserBookmark.csproj @@ -107,7 +107,7 @@ - +