mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
86 lines
3.1 KiB
C#
86 lines
3.1 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
using System.Runtime.InteropServices.ComTypes;
|
|
using Flow.Launcher.Plugin.Program.Logger;
|
|
using Windows.Win32.Foundation;
|
|
using Windows.Win32.UI.Shell;
|
|
using Windows.Win32.Storage.FileSystem;
|
|
|
|
namespace Flow.Launcher.Plugin.Program.Programs
|
|
{
|
|
class ShellLinkHelper
|
|
{
|
|
|
|
// Reference : http://www.pinvoke.net/default.aspx/Interfaces.IShellLinkW
|
|
[ComImport(), Guid("00021401-0000-0000-C000-000000000046")]
|
|
public class ShellLink
|
|
{
|
|
}
|
|
|
|
// To initialize the app description
|
|
public string description = string.Empty;
|
|
public string arguments = string.Empty;
|
|
|
|
// Retrieve the target path using Shell Link
|
|
public unsafe string retrieveTargetPath(string path)
|
|
{
|
|
var link = new ShellLink();
|
|
const int STGM_READ = 0;
|
|
((IPersistFile)link).Load(path, STGM_READ);
|
|
var hwnd = new HWND(IntPtr.Zero);
|
|
((IShellLinkW)link).Resolve(hwnd, 0);
|
|
|
|
const int MAX_PATH = 260;
|
|
char[] buffer = new char[MAX_PATH];
|
|
|
|
var data = new WIN32_FIND_DATAW();
|
|
var target = string.Empty;
|
|
fixed (char* bufferChar = buffer)
|
|
{
|
|
((IShellLinkW)link).GetPath((PWSTR)bufferChar, MAX_PATH, &data, (uint)SLGP_FLAGS.SLGP_SHORTPATH);
|
|
target = GetStringFromBuffer(buffer, MAX_PATH);
|
|
}
|
|
|
|
// To set the app description
|
|
if (!string.IsNullOrEmpty(target))
|
|
{
|
|
try
|
|
{
|
|
char[] buffer1 = new char[MAX_PATH];
|
|
fixed (char* buffer1Char = buffer1)
|
|
{
|
|
((IShellLinkW)link).GetDescription((PWSTR)buffer1Char, MAX_PATH);
|
|
description = GetStringFromBuffer(buffer1, MAX_PATH);
|
|
}
|
|
}
|
|
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);
|
|
}
|
|
|
|
char[] buffer2 = new char[MAX_PATH];
|
|
fixed (char* buffer2Char = buffer2)
|
|
{
|
|
((IShellLinkW)link).GetArguments((PWSTR)buffer2Char, MAX_PATH);
|
|
arguments = GetStringFromBuffer(buffer2, MAX_PATH);
|
|
}
|
|
}
|
|
|
|
// To release unmanaged memory
|
|
Marshal.ReleaseComObject(link);
|
|
|
|
return target;
|
|
}
|
|
|
|
private static unsafe string GetStringFromBuffer(char[] buffer, int maxLength)
|
|
{
|
|
// Truncate the buffer to the actual length of the string
|
|
int validLength = Array.IndexOf(buffer, '\0');
|
|
if (validLength < 0) validLength = maxLength;
|
|
return new string(buffer, 0, validLength);
|
|
}
|
|
}
|
|
}
|