Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Plugins/Flow.Launcher.Plugin.Program/NativeMethods.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ S_OK
SLGP_FLAGS
WIN32_FIND_DATAW
SLR_FLAGS
IShellLinkW
IShellItem
SHCreateItemFromParsingName
IShellLinkW
CoTaskMemFree
57 changes: 19 additions & 38 deletions Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLocalization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -21,46 +20,28 @@
/// <returns>The localized name as string or <see cref="string.Empty"/>.</returns>
public static unsafe string GetLocalizedName(string path)
{
const int capacity = 1024;
Span<char> 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);

Check warning on line 23 in Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLocalization.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`PInvoke` is not a recognized word. (unrecognized-spelling)
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);

Check warning on line 34 in Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLocalization.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`PInvoke` is not a recognized word. (unrecognized-spelling)

Check warning on line 34 in Plugins/Flow.Launcher.Plugin.Program/Programs/ShellLocalization.cs

View workflow job for this annotation

GitHub Actions / Check Spelling

`PInvoke` is not a recognized word. (unrecognized-spelling)
return filename;
}
catch
{
return string.Empty;
}
finally
{
Marshal.ReleaseComObject(shellItem);
}
}

/// <summary>
Expand Down
Loading