Skip to content

Commit 83883c4

Browse files
authored
Merge pull request #4195 from Flow-Launcher/fix-localized-name
Fix localized name search for Program plugin
2 parents 8e80c3b + b062fc0 commit 83883c4

2 files changed

Lines changed: 23 additions & 39 deletions

File tree

Plugins/Flow.Launcher.Plugin.Program/NativeMethods.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,7 @@ S_OK
77
SLGP_FLAGS
88
WIN32_FIND_DATAW
99
SLR_FLAGS
10-
IShellLinkW
10+
IShellItem
11+
SHCreateItemFromParsingName
12+
IShellLinkW
13+
CoTaskMemFree

Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLocalization.cs

Lines changed: 19 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using System.Runtime.InteropServices;
44
using Windows.Win32;
55
using Windows.Win32.Foundation;
6-
using Windows.Win32.System.LibraryLoader;
76

87
namespace Flow.Launcher.Plugin.Program.Programs
98
{
@@ -21,46 +20,28 @@ public static class ShellLocalization
2120
/// <returns>The localized name as string or <see cref="string.Empty"/>.</returns>
2221
public static unsafe string GetLocalizedName(string path)
2322
{
24-
const int capacity = 1024;
25-
Span<char> buffer = new char[capacity];
26-
27-
// If there is no resource to localize a file name the method returns a non zero value.
28-
fixed (char* bufferPtr = buffer)
23+
int retCode = PInvoke.SHCreateItemFromParsingName(path, null, typeof(Windows.Win32.UI.Shell.IShellItem).GUID, out object shellItemObj);
24+
if (retCode != 0 || shellItemObj is not Windows.Win32.UI.Shell.IShellItem shellItem)
2925
{
30-
int id;
31-
fixed (char* pathPtr = path)
32-
{
33-
var result = PInvoke.SHGetLocalizedName(new PCWSTR(pathPtr), bufferPtr, capacity, &id);
34-
35-
if (result != HRESULT.S_OK)
36-
{
37-
return string.Empty;
38-
}
39-
40-
var resourcePathStr = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(bufferPtr).ToString();
41-
fixed (char* resourcePathPtr = resourcePathStr)
42-
{
43-
_ = PInvoke.ExpandEnvironmentStrings(new PCWSTR(resourcePathPtr), bufferPtr, capacity);
44-
using var handle = PInvoke.LoadLibraryEx(resourcePathStr,
45-
LOAD_LIBRARY_FLAGS.DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_FLAGS.LOAD_LIBRARY_AS_DATAFILE);
46-
if (handle.IsInvalid)
47-
{
48-
return string.Empty;
49-
}
50-
51-
// not sure about the behavior of Pinvoke.LoadString, so we clear the buffer before using it (so it must be a null-terminated string)
52-
buffer.Clear();
53-
54-
if (PInvoke.LoadString(handle, (uint)id, buffer, capacity) != 0)
55-
{
56-
var lString = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(bufferPtr).ToString();
57-
return lString;
58-
}
59-
}
60-
}
26+
return string.Empty;
6127
}
6228

63-
return string.Empty;
29+
try
30+
{
31+
PWSTR displayName;
32+
shellItem.GetDisplayName(Windows.Win32.UI.Shell.SIGDN.SIGDN_NORMALDISPLAY, &displayName);
33+
string filename = displayName.ToString();
34+
PInvoke.CoTaskMemFree(displayName);
35+
return filename;
36+
}
37+
catch
38+
{
39+
return string.Empty;
40+
}
41+
finally
42+
{
43+
Marshal.ReleaseComObject(shellItem);
44+
}
6445
}
6546

6647
/// <summary>

0 commit comments

Comments
 (0)