/* Shortcut resolver. Avoids using IWshRuntimeLibrary Proposed by Sam Saffron @ StackOverflow */ using System; using System.Runtime.InteropServices; using System.Text; namespace Wox.Plugin.Program { public class ShortcutHelper { #region Signatures [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] struct WIN32_FIND_DATAW { public uint dwFileAttributes; public long ftCreationTime; public long ftLastAccessTime; public long ftLastWriteTime; public uint nFileSizeHigh; public uint nFileSizeLow; public uint dwReserved0; public uint dwReserved1; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string cFileName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)] public string cAlternateFileName; } /// The IShellLink interface allows Shell links to be created, modified, and resolved [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214F9-0000-0000-C000-000000000046")] interface IShellLinkW { /// Retrieves the path and file name of a Shell link object void GetPath([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out WIN32_FIND_DATAW pfd, uint fFlags); } [ComImport, Guid("0000010c-0000-0000-c000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IPersist { } [ComImport, Guid("0000010b-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IPersistFile : IPersist { new void GetClassID(out Guid pClassID); [PreserveSig] void Load([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName, uint dwMode); } const uint STGM_READ = 0; const int MAX_PATH = 260; // CLSID_ShellLink from ShlGuid.h [ ComImport(), Guid("00021401-0000-0000-C000-000000000046") ] public class ShellLink { } #endregion public static string ResolveShortcut(string filename) { ShellLink link = new ShellLink(); ((IPersistFile)link).Load(filename, STGM_READ); StringBuilder sb = new StringBuilder(MAX_PATH); WIN32_FIND_DATAW data = new WIN32_FIND_DATAW(); ((IShellLinkW)link).GetPath(sb, sb.Capacity, out data, 0); return sb.ToString(); } } }