diff --git a/src/modules/launcher/Wox.Infrastructure/Image/ImageLoader.cs b/src/modules/launcher/Wox.Infrastructure/Image/ImageLoader.cs index 4d1f75707997..0da3de80e7a6 100644 --- a/src/modules/launcher/Wox.Infrastructure/Image/ImageLoader.cs +++ b/src/modules/launcher/Wox.Infrastructure/Image/ImageLoader.cs @@ -55,13 +55,18 @@ public static bool IsValidPngSignature(string filePath) return fs.Read(buffer, 0, buffer.Length) == buffer.Length && pngSignature.SequenceEqual(buffer); } + internal static string GetNormalizedPath(string path) + { + return PathNormalization.NormalizePath(path); + } + public static void Initialize() { _hashGenerator = new ImageHashGenerator(); foreach (var icon in new[] { Constant.ErrorIcon, Constant.LightThemedErrorIcon }) { - var uri = new Uri(icon); + var uri = new Uri(GetNormalizedPath(icon)); try { @@ -298,7 +303,7 @@ private static BitmapImage LoadFullImage(string path) BitmapImage image = new BitmapImage(); image.BeginInit(); image.CacheOption = BitmapCacheOption.OnLoad; - image.UriSource = new Uri(path); + image.UriSource = new Uri(GetNormalizedPath(path)); image.EndInit(); return image; } diff --git a/src/modules/launcher/Wox.Plugin/Constant.cs b/src/modules/launcher/Wox.Plugin/Constant.cs index 18245bb6c2f4..9866fab6f32c 100644 --- a/src/modules/launcher/Wox.Plugin/Constant.cs +++ b/src/modules/launcher/Wox.Plugin/Constant.cs @@ -64,7 +64,7 @@ public static string DetermineDataDirectory() public static readonly string Version = FileVersionInfo.GetVersionInfo(Assembly.Location.NonNull()).ProductVersion; public static readonly int ThumbnailSize = 64; - public static readonly string ErrorIcon = Path.Combine(ProgramDirectory, "Assets", "PowerLauncher", "app_error.dark.png"); - public static readonly string LightThemedErrorIcon = Path.Combine(ProgramDirectory, "Assets", "PowerLauncher", "app_error.light.png"); + public static readonly string ErrorIcon = PathNormalization.NormalizePath(Path.Combine(ProgramDirectory, "Assets", "PowerLauncher", "app_error.dark.png")); + public static readonly string LightThemedErrorIcon = PathNormalization.NormalizePath(Path.Combine(ProgramDirectory, "Assets", "PowerLauncher", "app_error.light.png")); } } diff --git a/src/modules/launcher/Wox.Plugin/PathNormalization.cs b/src/modules/launcher/Wox.Plugin/PathNormalization.cs new file mode 100644 index 000000000000..6396e72d6353 --- /dev/null +++ b/src/modules/launcher/Wox.Plugin/PathNormalization.cs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace Wox.Plugin +{ + public static class PathNormalization + { + private const string UncPrefix = @"\\?\UNC\"; + private const string ExtendedPrefix = @"\\?\"; + + public static string NormalizePath(string path) + { + if (path.StartsWith(UncPrefix, StringComparison.OrdinalIgnoreCase)) + { + return @"\\" + path.Substring(UncPrefix.Length); + } + + if (path.StartsWith(ExtendedPrefix, StringComparison.OrdinalIgnoreCase)) + { + return path.Substring(ExtendedPrefix.Length); + } + + return path; + } + } +} diff --git a/src/modules/launcher/Wox.Test/ImageLoaderTest.cs b/src/modules/launcher/Wox.Test/ImageLoaderTest.cs new file mode 100644 index 000000000000..e568974e9402 --- /dev/null +++ b/src/modules/launcher/Wox.Test/ImageLoaderTest.cs @@ -0,0 +1,41 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Wox.Plugin; + +namespace Wox.Test +{ + [TestClass] + public class ImageLoaderTest + { + [DataTestMethod] + + // Regular Windows paths should be returned unchanged + [DataRow(@"C:\path\to\file.png", @"C:\path\to\file.png")] + [DataRow(@"C:\Program Files\PowerToys\Assets\PowerLauncher\app_error.dark.png", @"C:\Program Files\PowerToys\Assets\PowerLauncher\app_error.dark.png")] + + // UNC paths should be returned unchanged + [DataRow(@"\\server\share\path\file.png", @"\\server\share\path\file.png")] + + // Extended-length local paths (\\?\C:\...) should have the \\?\ prefix stripped + [DataRow(@"\\?\C:\path\to\file.png", @"C:\path\to\file.png")] + [DataRow(@"\\?\C:\Program Files\PowerToys\Assets\app_error.dark.png", @"C:\Program Files\PowerToys\Assets\app_error.dark.png")] + + // Extended-length UNC paths (\\?\UNC\server\...) should be converted to \\server\... + [DataRow(@"\\?\UNC\server\share\path\file.png", @"\\server\share\path\file.png")] + [DataRow(@"\\?\UNC\TH50\TH50_c\Program Files\PowerToys\Assets\PowerLauncher\app_error.dark.png", @"\\TH50\TH50_c\Program Files\PowerToys\Assets\PowerLauncher\app_error.dark.png")] + + // Case-insensitive matching for the prefix + [DataRow(@"\\?\unc\server\share\path\file.png", @"\\server\share\path\file.png")] + public void GetNormalizedPath_ShouldStripExtendedLengthPrefix(string input, string expected) + { + // Act + string result = PathNormalization.NormalizePath(input); + + // Assert + Assert.AreEqual(expected, result); + } + } +}