From dd65c173a95920697d5cf10c815374d4c6cbf23a Mon Sep 17 00:00:00 2001 From: Boris Makogonyuk Date: Sun, 13 Dec 2015 20:58:51 +0100 Subject: [PATCH 1/3] Bugfix for #404 When opening containing folder for `*.lnk` that cannot be resolved to a file name, the folder containing the `.lnk` will be opened. --- Plugins/Wox.Plugin.Program/Programs.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Plugins/Wox.Plugin.Program/Programs.cs b/Plugins/Wox.Plugin.Program/Programs.cs index 347f640b8a..66c4685dca 100644 --- a/Plugins/Wox.Plugin.Program/Programs.cs +++ b/Plugins/Wox.Plugin.Program/Programs.cs @@ -224,7 +224,9 @@ namespace Wox.Plugin.Program if (Path.EndsWith(".lnk")) { //get location of shortcut - Path = ResolveShortcut(Path); + var resolved = ResolveShortcut(Path); + if(!string.IsNullOrEmpty(resolved)) + Path = resolved; } //get parent folder Path = Directory.GetParent(Path).FullName; From ba8300508d97b9604718c725f8835d30cd6fc53b Mon Sep 17 00:00:00 2001 From: Boris Makogonyuk Date: Sun, 13 Dec 2015 22:22:17 +0100 Subject: [PATCH 2/3] - Removed IWshRuntimeLibrary. It is no longer needed for the plugin. - Added ShortcutHelper for invocation calls. --- Plugins/Wox.Plugin.Program/Programs.cs | 11 +- Plugins/Wox.Plugin.Program/ShortcutHelper.cs | 178 ++++++++++++++++++ .../Wox.Plugin.Program.csproj | 12 +- 3 files changed, 180 insertions(+), 21 deletions(-) create mode 100644 Plugins/Wox.Plugin.Program/ShortcutHelper.cs diff --git a/Plugins/Wox.Plugin.Program/Programs.cs b/Plugins/Wox.Plugin.Program/Programs.cs index 66c4685dca..90604cf702 100644 --- a/Plugins/Wox.Plugin.Program/Programs.cs +++ b/Plugins/Wox.Plugin.Program/Programs.cs @@ -5,7 +5,6 @@ using System.IO; using System.Linq; using System.Reflection; using System.Windows; -using IWshRuntimeLibrary; using Wox.Infrastructure; using Wox.Plugin.Program.ProgramSources; using Wox.Infrastructure.Logger; @@ -50,14 +49,6 @@ namespace Wox.Plugin.Program return results; } - static string ResolveShortcut(string filePath) - { - // IWshRuntimeLibrary is in the COM library "Windows Script Host Object Model" - WshShell shell = new WshShell(); - IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(filePath); - return shortcut.TargetPath; - } - private bool MatchProgram(Program program, FuzzyMatcher matcher) { var scores = new List { program.Title, program.PinyinTitle, program.AbbrTitle, program.ExecuteName }; @@ -224,7 +215,7 @@ namespace Wox.Plugin.Program if (Path.EndsWith(".lnk")) { //get location of shortcut - var resolved = ResolveShortcut(Path); + var resolved = ShortcutHelper.ResolveShortcut(Path); if(!string.IsNullOrEmpty(resolved)) Path = resolved; } diff --git a/Plugins/Wox.Plugin.Program/ShortcutHelper.cs b/Plugins/Wox.Plugin.Program/ShortcutHelper.cs new file mode 100644 index 0000000000..65a5f44530 --- /dev/null +++ b/Plugins/Wox.Plugin.Program/ShortcutHelper.cs @@ -0,0 +1,178 @@ +/* + 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 + [DllImport("shfolder.dll", CharSet = CharSet.Auto)] + internal static extern int SHGetFolderPath(IntPtr hwndOwner, int nFolder, IntPtr hToken, int dwFlags, StringBuilder lpszPath); + + [Flags()] + enum SLGP_FLAGS + { + /// Retrieves the standard short (8.3 format) file name + SLGP_SHORTPATH = 0x1, + /// Retrieves the Universal Naming Convention (UNC) path name of the file + SLGP_UNCPRIORITY = 0x2, + /// Retrieves the raw path name. A raw path is something that might not exist and may include environment variables that need to be expanded + SLGP_RAWPATH = 0x4 + } + + [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; + } + + [Flags()] + enum SLR_FLAGS + { + /// + /// Do not display a dialog box if the link cannot be resolved. When SLR_NO_UI is set, + /// the high-order word of fFlags can be set to a time-out value that specifies the + /// maximum amount of time to be spent resolving the link. The function returns if the + /// link cannot be resolved within the time-out duration. If the high-order word is set + /// to zero, the time-out duration will be set to the default value of 3,000 milliseconds + /// (3 seconds). To specify a value, set the high word of fFlags to the desired time-out + /// duration, in milliseconds. + /// + SLR_NO_UI = 0x1, + /// Obsolete and no longer used + SLR_ANY_MATCH = 0x2, + /// If the link object has changed, update its path and list of identifiers. + /// If SLR_UPDATE is set, you do not need to call IPersistFile::IsDirty to determine + /// whether or not the link object has changed. + SLR_UPDATE = 0x4, + /// Do not update the link information + SLR_NOUPDATE = 0x8, + /// Do not execute the search heuristics + SLR_NOSEARCH = 0x10, + /// Do not use distributed link tracking + SLR_NOTRACK = 0x20, + /// Disable distributed link tracking. By default, distributed link tracking tracks + /// removable media across multiple devices based on the volume name. It also uses the + /// Universal Naming Convention (UNC) path to track remote file systems whose drive letter + /// has changed. Setting SLR_NOLINKINFO disables both types of tracking. + SLR_NOLINKINFO = 0x40, + /// Call the Microsoft Windows Installer + SLR_INVOKE_MSI = 0x80 + } + + + /// 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, SLGP_FLAGS fFlags); + /// Retrieves the list of item identifiers for a Shell link object + void GetIDList(out IntPtr ppidl); + /// Sets the pointer to an item identifier list (PIDL) for a Shell link object. + void SetIDList(IntPtr pidl); + /// Retrieves the description string for a Shell link object + void GetDescription([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName); + /// Sets the description for a Shell link object. The description can be any application-defined string + void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName); + /// Retrieves the name of the working directory for a Shell link object + void GetWorkingDirectory([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath); + /// Sets the name of the working directory for a Shell link object + void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir); + /// Retrieves the command-line arguments associated with a Shell link object + void GetArguments([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath); + /// Sets the command-line arguments for a Shell link object + void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs); + /// Retrieves the hot key for a Shell link object + void GetHotkey(out short pwHotkey); + /// Sets a hot key for a Shell link object + void SetHotkey(short wHotkey); + /// Retrieves the show command for a Shell link object + void GetShowCmd(out int piShowCmd); + /// Sets the show command for a Shell link object. The show command sets the initial show state of the window. + void SetShowCmd(int iShowCmd); + /// Retrieves the location (path and index) of the icon for a Shell link object + void GetIconLocation([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, + int cchIconPath, out int piIcon); + /// Sets the location (path and index) of the icon for a Shell link object + void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon); + /// Sets the relative path to the Shell link object + void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved); + /// Attempts to find the target of a Shell link, even if it has been moved or renamed + void Resolve(IntPtr hwnd, SLR_FLAGS fFlags); + /// Sets the path and file name of a Shell link object + void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile); + + } + + [ComImport, Guid("0000010c-0000-0000-c000-000000000046"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IPersist + { + [PreserveSig] + void GetClassID(out Guid pClassID); + } + + + [ComImport, Guid("0000010b-0000-0000-C000-000000000046"), + InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + public interface IPersistFile : IPersist + { + new void GetClassID(out Guid pClassID); + [PreserveSig] + int IsDirty(); + + [PreserveSig] + void Load([In, MarshalAs(UnmanagedType.LPWStr)] + string pszFileName, uint dwMode); + + [PreserveSig] + void Save([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName, + [In, MarshalAs(UnmanagedType.Bool)] bool fRemember); + + [PreserveSig] + void SaveCompleted([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName); + + [PreserveSig] + void GetCurFile([In, MarshalAs(UnmanagedType.LPWStr)] string ppszFileName); + } + + 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(); + } + } +} diff --git a/Plugins/Wox.Plugin.Program/Wox.Plugin.Program.csproj b/Plugins/Wox.Plugin.Program/Wox.Plugin.Program.csproj index 784a900d92..5eac4a7511 100644 --- a/Plugins/Wox.Plugin.Program/Wox.Plugin.Program.csproj +++ b/Plugins/Wox.Plugin.Program/Wox.Plugin.Program.csproj @@ -71,6 +71,7 @@ ProgramSuffixes.xaml + @@ -126,17 +127,6 @@ Wox.Plugin - - - {F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} - 1 - 0 - 0 - tlbimp - False - True - -