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

85 lines
3 KiB
C#
Raw Normal View History

using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
2022-12-31 13:02:27 +00:00
using Flow.Launcher.Plugin.Program.Logger;
2024-12-10 07:09:06 +00:00
using Windows.Win32.Foundation;
using Windows.Win32.UI.Shell;
using Windows.Win32.Storage.FileSystem;
2020-06-24 02:55:21 +00:00
namespace Flow.Launcher.Plugin.Program.Programs
{
class ShellLinkHelper
{
2024-12-10 07:09:06 +00:00
// Reference : http://www.pinvoke.net/default.aspx/Interfaces.IShellLinkW
[ComImport(), Guid("00021401-0000-0000-C000-000000000046")]
public class ShellLink
{
}
// To initialize the app description
2022-11-21 11:36:11 +00:00
public string description = string.Empty;
public string arguments = string.Empty;
// Retrieve the target path using Shell Link
2024-12-10 07:09:06 +00:00
public unsafe string retrieveTargetPath(string path)
{
var link = new ShellLink();
const int STGM_READ = 0;
((IPersistFile)link).Load(path, STGM_READ);
2024-12-10 07:09:06 +00:00
var hwnd = new HWND(IntPtr.Zero);
((IShellLinkW)link).Resolve(hwnd, 0);
const int MAX_PATH = 260;
Span<char> buffer = stackalloc char[MAX_PATH];
var data = new WIN32_FIND_DATAW();
2024-12-10 07:09:06 +00:00
var target = string.Empty;
try
2024-12-10 07:09:06 +00:00
{
fixed (char* bufferPtr = buffer)
{
((IShellLinkW)link).GetPath((PWSTR)bufferPtr, MAX_PATH, &data, (uint)SLGP_FLAGS.SLGP_SHORTPATH);
target = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(bufferPtr).ToString();
}
}
catch (COMException e)
{
ProgramLogger.LogException($"|IShellLinkW|retrieveTargetPath|{path}" +
"|Error occurred while getting program arguments", e);
2024-12-10 07:09:06 +00:00
}
// To set the app description
2024-12-10 07:09:06 +00:00
if (!string.IsNullOrEmpty(target))
{
2022-12-31 13:02:27 +00:00
try
{
fixed (char* bufferPtr = buffer)
2024-12-10 07:09:06 +00:00
{
((IShellLinkW)link).GetDescription(bufferPtr, MAX_PATH);
description = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(bufferPtr).ToString();
2024-12-10 07:09:06 +00:00
}
2022-12-31 13:02:27 +00:00
}
catch (COMException e)
{
// C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\MiracastView.lnk always cause exception
ProgramLogger.LogException($"|IShellLinkW|retrieveTargetPath|{path}" +
"|Error caused likely due to trying to get the description of the program",
e);
}
2022-11-21 11:36:11 +00:00
fixed (char* bufferPtr = buffer)
2024-12-10 07:09:06 +00:00
{
((IShellLinkW)link).GetArguments(bufferPtr, MAX_PATH);
arguments = MemoryMarshal.CreateReadOnlySpanFromNullTerminated(bufferPtr).ToString();
2024-12-10 07:09:06 +00:00
}
}
// To release unmanaged memory
Marshal.ReleaseComObject(link);
return target;
}
}
2022-11-21 11:36:11 +00:00
}