diff --git a/Plugins/Flow.Launcher.Plugin.Program/NativeMethods.txt b/Plugins/Flow.Launcher.Plugin.Program/NativeMethods.txt index ecd547dffcd..a8fe178c7a2 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/NativeMethods.txt +++ b/Plugins/Flow.Launcher.Plugin.Program/NativeMethods.txt @@ -7,4 +7,7 @@ S_OK SLGP_FLAGS WIN32_FIND_DATAW SLR_FLAGS -IShellLinkW \ No newline at end of file +IShellItem +SHCreateItemFromParsingName +IShellLinkW +CoTaskMemFree \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLocalization.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLocalization.cs index 5c2f6f9762d..815b74b966a 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLocalization.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLocalization.cs @@ -3,7 +3,6 @@ using System.Runtime.InteropServices; using Windows.Win32; using Windows.Win32.Foundation; -using Windows.Win32.System.LibraryLoader; namespace Flow.Launcher.Plugin.Program.Programs { @@ -21,46 +20,28 @@ public static class ShellLocalization /// The localized name as string or . public static unsafe string GetLocalizedName(string path) { - const int capacity = 1024; - Span buffer = new char[capacity]; - - // If there is no resource to localize a file name the method returns a non zero value. - fixed (char* bufferPtr = buffer) + int retCode = PInvoke.SHCreateItemFromParsingName(path, null, typeof(Windows.Win32.UI.Shell.IShellItem).GUID, out object shellItemObj); + if (retCode != 0 || shellItemObj is not Windows.Win32.UI.Shell.IShellItem shellItem) { - int id; - fixed (char* pathPtr = path) - { - var result = PInvoke.SHGetLocalizedName(new PCWSTR(pathPtr), bufferPtr, capacity, &id); - - if (result != HRESULT.S_OK) - { - return string.Empty; - } - - var resourcePathStr = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(bufferPtr).ToString(); - fixed (char* resourcePathPtr = resourcePathStr) - { - _ = PInvoke.ExpandEnvironmentStrings(new PCWSTR(resourcePathPtr), bufferPtr, capacity); - using var handle = PInvoke.LoadLibraryEx(resourcePathStr, - LOAD_LIBRARY_FLAGS.DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_FLAGS.LOAD_LIBRARY_AS_DATAFILE); - if (handle.IsInvalid) - { - return string.Empty; - } - - // not sure about the behavior of Pinvoke.LoadString, so we clear the buffer before using it (so it must be a null-terminated string) - buffer.Clear(); - - if (PInvoke.LoadString(handle, (uint)id, buffer, capacity) != 0) - { - var lString = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(bufferPtr).ToString(); - return lString; - } - } - } + return string.Empty; } - return string.Empty; + try + { + PWSTR displayName; + shellItem.GetDisplayName(Windows.Win32.UI.Shell.SIGDN.SIGDN_NORMALDISPLAY, &displayName); + string filename = displayName.ToString(); + PInvoke.CoTaskMemFree(displayName); + return filename; + } + catch + { + return string.Empty; + } + finally + { + Marshal.ReleaseComObject(shellItem); + } } ///