diff --git a/Wox/MainWindow.xaml.cs b/Wox/MainWindow.xaml.cs
index dafc53f4a3..9b785e7f9f 100644
--- a/Wox/MainWindow.xaml.cs
+++ b/Wox/MainWindow.xaml.cs
@@ -24,6 +24,7 @@ using Wox.Helper;
using Wox.Infrastructure;
using Wox.Infrastructure.Hotkey;
using Wox.Plugin;
+using Wox.ShellContext;
using Wox.Storage;
using ContextMenu = System.Windows.Forms.ContextMenu;
using DataFormats = System.Windows.DataFormats;
@@ -278,6 +279,7 @@ namespace Wox
InitProgressbarAnimation();
WindowIntelopHelper.DisableControlBox(this);
CheckUpdate();
+ new ShellContextMenuManager().GetContextMenus(@"c:\Windows\write.exe");
}
private void CheckUpdate()
diff --git a/Wox/ShellContext/Enums.cs b/Wox/ShellContext/Enums.cs
new file mode 100644
index 0000000000..859c637d43
--- /dev/null
+++ b/Wox/ShellContext/Enums.cs
@@ -0,0 +1,209 @@
+using System;
+
+namespace Wox.ShellContext
+{
+ [Flags()]
+ public enum SHCONTF
+ {
+ FOLDERS = 0x20,
+ NONFOLDERS = 0x40,
+ INCLUDEHIDDEN = 0x80,
+ INIT_ON_FIRST_NEXT = 0x100,
+ NETPRINTERSRCH = 0x200,
+ SHAREABLE = 0x400,
+ STORAGE = 0x800
+ }
+
+ [Flags()]
+ public enum SFGAO
+ {
+ CANCOPY = 0x1,
+ CANMOVE = 0x2,
+ CANLINK = 0x4,
+ STORAGE = 0x8,
+ CANRENAME = 0x10,
+ CANDELETE = 0x20,
+ HASPROPSHEET = 0x40,
+ DROPTARGET = 0x100,
+ CAPABILITYMASK = 0x177,
+ ENCRYPTED = 0x2000,
+ ISSLOW = 0x4000,
+ GHOSTED = 0x8000,
+ LINK = 0x10000,
+ SHARE = 0x20000,
+ READONLY = 0x40000,
+ HIDDEN = 0x80000,
+ DISPLAYATTRMASK = 0xFC000,
+ FILESYSANCESTOR = 0x10000000,
+ FOLDER = 0x20000000,
+ FILESYSTEM = 0x40000000,
+ HASSUBFOLDER = unchecked((int)0x80000000),
+ CONTENTSMASK = unchecked((int)0x80000000),
+ VALIDATE = 0x1000000,
+ REMOVABLE = 0x2000000,
+ COMPRESSED = 0x4000000,
+ BROWSABLE = 0x8000000,
+ NONENUMERATED = 0x100000,
+ NEWCONTENT = 0x200000,
+ CANMONIKER = 0x400000,
+ HASSTORAGE = 0x400000,
+ STREAM = 0x400000,
+ STORAGEANCESTOR = 0x800000,
+ STORAGECAPMASK = 0x70C50008
+ }
+
+ [Flags()]
+ public enum SHGNO
+ {
+ NORMAL = 0x0,
+ INFOLDER = 0x1,
+ FOREDITING = 0x1000,
+ FORADDRESSBAR = 0x4000,
+ FORPARSING = 0x8000,
+ }
+
+ [Flags()]
+ public enum CSIDL
+ {
+ ADMINTOOLS = 0x30,
+ ALTSTARTUP = 0x1d,
+ APPDATA = 0x1a,
+ BITBUCKET = 10,
+ CDBURN_AREA = 0x3b,
+ COMMON_ADMINTOOLS = 0x2f,
+ COMMON_ALTSTARTUP = 30,
+ COMMON_APPDATA = 0x23,
+ COMMON_DESKTOPDIRECTORY = 0x19,
+ COMMON_DOCUMENTS = 0x2e,
+ COMMON_FAVORITES = 0x1f,
+ COMMON_MUSIC = 0x35,
+ COMMON_PICTURES = 0x36,
+ COMMON_PROGRAMS = 0x17,
+ COMMON_STARTMENU = 0x16,
+ COMMON_STARTUP = 0x18,
+ COMMON_TEMPLATES = 0x2d,
+ COMMON_VIDEO = 0x37,
+ CONTROLS = 3,
+ COOKIES = 0x21,
+ DESKTOP = 0,
+ DESKTOPDIRECTORY = 0x10,
+ DRIVES = 0x11,
+ FAVORITES = 6,
+ FLAG_CREATE = 0x8000,
+ FONTS = 20,
+ HISTORY = 0x22,
+ INTERNET = 1,
+ INTERNET_CACHE = 0x20,
+ LOCAL_APPDATA = 0x1c,
+ MYDOCUMENTS = 12,
+ MYMUSIC = 13,
+ MYPICTURES = 0x27,
+ MYVIDEO = 14,
+ NETHOOD = 0x13,
+ NETWORK = 0x12,
+ PERSONAL = 5,
+ PRINTERS = 4,
+ PRINTHOOD = 0x1b,
+ PROFILE = 40,
+ PROFILES = 0x3e,
+ PROGRAM_FILES = 0x26,
+ PROGRAM_FILES_COMMON = 0x2b,
+ PROGRAMS = 2,
+ RECENT = 8,
+ SENDTO = 9,
+ STARTMENU = 11,
+ STARTUP = 7,
+ SYSTEM = 0x25,
+ TEMPLATES = 0x15,
+ WINDOWS = 0x24
+ }
+
+ [Flags()]
+ public enum SHGFI : uint
+ {
+ ADDOVERLAYS = 0x20,
+ ATTR_SPECIFIED = 0x20000,
+ ATTRIBUTES = 0x800,
+ DISPLAYNAME = 0x200,
+ EXETYPE = 0x2000,
+ ICON = 0x100,
+ ICONLOCATION = 0x1000,
+ LARGEICON = 0,
+ LINKOVERLAY = 0x8000,
+ OPENICON = 2,
+ OVERLAYINDEX = 0x40,
+ PIDL = 8,
+ SELECTED = 0x10000,
+ SHELLICONSIZE = 4,
+ SMALLICON = 1,
+ SYSICONINDEX = 0x4000,
+ TYPENAME = 0x400,
+ USEFILEATTRIBUTES = 0x10
+ }
+
+ [Flags]
+ public enum FILE_ATTRIBUTE
+ {
+ READONLY = 0x00000001,
+ HIDDEN = 0x00000002,
+ SYSTEM = 0x00000004,
+ DIRECTORY = 0x00000010,
+ ARCHIVE = 0x00000020,
+ DEVICE = 0x00000040,
+ NORMAL = 0x00000080,
+ TEMPORARY = 0x00000100,
+ SPARSE_FILE = 0x00000200,
+ REPARSE_POINT = 0x00000400,
+ COMPRESSED = 0x00000800,
+ OFFLINE = 0x00001000,
+ NOT_CONTENT_INDEXED = 0x00002000,
+ ENCRYPTED = 0x00004000
+ }
+
+ public enum GetCommandStringInformations
+ {
+ VERB = 0x00000004,
+ HELPTEXT = 0x00000005,
+ VALIDATE = 0x00000006,
+ }
+
+ [Flags]
+ public enum CMF : uint
+ {
+ NORMAL = 0x00000000,
+ DEFAULTONLY = 0x00000001,
+ VERBSONLY = 0x00000002,
+ EXPLORE = 0x00000004,
+ NOVERBS = 0x00000008,
+ CANRENAME = 0x00000010,
+ NODEFAULT = 0x00000020,
+ INCLUDESTATIC = 0x00000040,
+ EXTENDEDVERBS = 0x00000100,
+ RESERVED = 0xffff0000
+ }
+
+ [Flags]
+ public enum TPM : uint
+ {
+ LEFTBUTTON = 0x0000,
+ RIGHTBUTTON = 0x0002,
+ LEFTALIGN = 0x0000,
+ CENTERALIGN = 0x0004,
+ RIGHTALIGN = 0x0008,
+ TOPALIGN = 0x0000,
+ VCENTERALIGN = 0x0010,
+ BOTTOMALIGN = 0x0020,
+ HORIZONTAL = 0x0000,
+ VERTICAL = 0x0040,
+ NONOTIFY = 0x0080,
+ RETURNCMD = 0x0100,
+ RECURSE = 0x0001,
+ HORPOSANIMATION = 0x0400,
+ HORNEGANIMATION = 0x0800,
+ VERPOSANIMATION = 0x1000,
+ VERNEGANIMATION = 0x2000,
+ NOANIMATION = 0x4000,
+ LAYOUTRTL = 0x8000
+ }
+
+}
diff --git a/Wox/ShellContext/Guids.cs b/Wox/ShellContext/Guids.cs
new file mode 100644
index 0000000000..d8a44e3956
--- /dev/null
+++ b/Wox/ShellContext/Guids.cs
@@ -0,0 +1,29 @@
+using System;
+
+namespace Wox.ShellContext
+{
+ public class Guids
+ {
+ public static Guid IID_DesktopGUID = new Guid("{00021400-0000-0000-C000-000000000046}");
+
+ public static Guid IID_IShellFolder = new Guid("{000214E6-0000-0000-C000-000000000046}");
+ public static Guid IID_IContextMenu = new Guid("{000214e4-0000-0000-c000-000000000046}");
+ public static Guid IID_IContextMenu2 = new Guid("{000214f4-0000-0000-c000-000000000046}");
+ public static Guid IID_IContextMenu3 = new Guid("{bcfce0a0-ec17-11d0-8d10-00a0c90f2719}");
+
+ public static Guid IID_IDropTarget = new Guid("{00000122-0000-0000-C000-000000000046}");
+ public static Guid IID_IDataObject = new Guid("{0000010e-0000-0000-C000-000000000046}");
+
+ public static Guid IID_IQueryInfo = new Guid("{00021500-0000-0000-C000-000000000046}");
+ public static Guid IID_IPersistFile = new Guid("{0000010b-0000-0000-C000-000000000046}");
+
+ public static Guid CLSID_DragDropHelper = new Guid("{4657278A-411B-11d2-839A-00C04FD918D0}");
+ public static Guid CLSID_NewMenu = new Guid("{D969A300-E7FF-11d0-A93B-00A0C90F2719}");
+ public static Guid IID_IDragSourceHelper = new Guid("{DE5BF786-477A-11d2-839D-00C04FD918D0}");
+ public static Guid IID_IDropTargetHelper = new Guid("{4657278B-411B-11d2-839A-00C04FD918D0}");
+
+ public static Guid IID_IShellExtInit = new Guid("{000214e8-0000-0000-c000-000000000046}");
+ public static Guid IID_IStream = new Guid("{0000000c-0000-0000-c000-000000000046}");
+ public static Guid IID_IStorage = new Guid("{0000000B-0000-0000-C000-000000000046}");
+ }
+}
diff --git a/Wox/ShellContext/IContextMenu.cs b/Wox/ShellContext/IContextMenu.cs
new file mode 100644
index 0000000000..2fe5e67bb2
--- /dev/null
+++ b/Wox/ShellContext/IContextMenu.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Wox.ShellContext
+{
+ [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214e4-0000-0000-c000-000000000046")]
+ public interface IContextMenu
+ {
+ [PreserveSig()]
+ Int32 QueryContextMenu(
+ IntPtr hmenu,
+ uint iMenu,
+ uint idCmdFirst,
+ uint idCmdLast,
+ CMF uFlags);
+
+ [PreserveSig()]
+ Int32 InvokeCommand(
+ ref CMINVOKECOMMANDINFOEX info);
+
+ [PreserveSig()]
+ void GetCommandString(
+ int idcmd,
+ GetCommandStringInformations uflags,
+ int reserved,
+ StringBuilder commandstring,
+ int cch);
+ }
+}
diff --git a/Wox/ShellContext/IEnumIDList.cs b/Wox/ShellContext/IEnumIDList.cs
new file mode 100644
index 0000000000..e32d22f06b
--- /dev/null
+++ b/Wox/ShellContext/IEnumIDList.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Wox.ShellContext
+{
+ [ComImport(),
+ Guid("000214F2-0000-0000-C000-000000000046"),
+ InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ public interface IEnumIDList
+ {
+ [PreserveSig()]
+ uint Next(
+ uint celt,
+ out IntPtr rgelt,
+ out int pceltFetched);
+
+ void Skip(
+ uint celt);
+
+ void Reset();
+
+ IEnumIDList Clone();
+ }
+}
diff --git a/Wox/ShellContext/IShellFolder.cs b/Wox/ShellContext/IShellFolder.cs
new file mode 100644
index 0000000000..cd7812bdc4
--- /dev/null
+++ b/Wox/ShellContext/IShellFolder.cs
@@ -0,0 +1,77 @@
+锘縰sing System;
+using System.Runtime.InteropServices;
+
+namespace Wox.ShellContext
+{
+ [ComImport]
+ [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ [Guid("000214E6-0000-0000-C000-000000000046")]
+ public interface IShellFolder
+ {
+ void ParseDisplayName(
+ IntPtr hwnd,
+ IntPtr pbc,
+ [MarshalAs(UnmanagedType.LPWStr)] string pszDisplayName,
+ out uint pchEaten,
+ out IntPtr ppidl,
+ ref uint pdwAttributes);
+
+ [PreserveSig]
+ int EnumObjects(IntPtr hWnd, SHCONTF flags, out IntPtr enumIDList);
+
+ void BindToObject(
+ IntPtr pidl,
+ IntPtr pbc,
+ [In()] ref Guid riid,
+ out IShellFolder ppv);
+
+ void BindToStorage(
+ IntPtr pidl,
+ IntPtr pbc,
+ [In()] ref Guid riid,
+ [MarshalAs(UnmanagedType.Interface)] out object ppv);
+
+ [PreserveSig()]
+ uint CompareIDs(
+ int lParam,
+ IntPtr pidl1,
+ IntPtr pidl2);
+
+ void CreateViewObject(
+ IntPtr hwndOwner,
+ [In()] ref Guid riid,
+ [MarshalAs(UnmanagedType.Interface)] out object ppv);
+
+ void GetAttributesOf(
+ uint cidl,
+ [In(), MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl,
+ ref SFGAO rgfInOut);
+
+ //[PreserveSig]
+ //Int32 GetUIObjectOf(
+ // IntPtr hwndOwner,
+ // uint cidl,
+ // [MarshalAs(UnmanagedType.LPArray)]
+ // IntPtr[] apidl,
+ // Guid riid,
+ // IntPtr rgfReserved,
+ // out IntPtr ppv);
+ IntPtr GetUIObjectOf(
+ IntPtr hwndOwner,
+ uint cidl,
+ [MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl,
+ [In()] ref Guid riid,
+ out IntPtr rgfReserved);
+
+ void GetDisplayNameOf(
+ IntPtr pidl,
+ SHGNO uFlags,
+ IntPtr lpName);
+
+ IntPtr SetNameOf(
+ IntPtr hwnd,
+ IntPtr pidl,
+ [MarshalAs(UnmanagedType.LPWStr)] string pszName,
+ SHGNO uFlags);
+ }
+}
diff --git a/Wox/ShellContext/ShellAPI.cs b/Wox/ShellContext/ShellAPI.cs
new file mode 100644
index 0000000000..cfcccab6bc
--- /dev/null
+++ b/Wox/ShellContext/ShellAPI.cs
@@ -0,0 +1,175 @@
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Wox.ShellContext
+{
+ public class ShellAPI
+ {
+ #region API 导入
+
+
+ public const int MAX_PATH = 260;
+ public const int S_OK = 0;
+ public const int S_FALSE = 1;
+ public const uint CMD_FIRST = 1;
+ public const uint CMD_LAST = 30000;
+
+ public const Int32 MF_BYPOSITION = 0x400;
+ [DllImport("user32.dll")]
+ public static extern bool DeleteMenu(IntPtr hMenu, uint uPosition, uint uFlags);
+ [DllImport("user32.dll")]
+ public static extern int GetMenuItemCount(IntPtr hMenu);
+
+ [DllImport("user32.dll")]
+ public static extern int GetMenuString(IntPtr hMenu, uint uIDItem, [Out, MarshalAs(UnmanagedType.LPStr)] StringBuilder lpString, int nMaxCount, uint uFlag);
+
+
+ [DllImport("shell32.dll")]
+ public static extern Int32 SHGetDesktopFolder(out IntPtr ppshf);
+
+ [DllImport("Shlwapi.Dll", CharSet = CharSet.Auto)]
+ public static extern Int32 StrRetToBuf(IntPtr pstr, IntPtr pidl, StringBuilder pszBuf, int cchBuf);
+
+ [DllImport("shell32.dll")]
+ public static extern int SHGetSpecialFolderLocation(IntPtr handle, CSIDL nFolder, out IntPtr ppidl);
+
+ [DllImport("shell32",
+ EntryPoint = "SHGetFileInfo",
+ ExactSpelling = false,
+ CharSet = CharSet.Auto,
+ SetLastError = true)]
+ public static extern IntPtr SHGetFileInfo(
+ IntPtr ppidl,
+ FILE_ATTRIBUTE dwFileAttributes,
+ ref SHFILEINFO sfi,
+ int cbFileInfo,
+ SHGFI uFlags);
+
+ [DllImport("user32",
+ SetLastError = true,
+ CharSet = CharSet.Auto)]
+ public static extern IntPtr CreatePopupMenu();
+
+ [DllImport("user32.dll",
+ ExactSpelling = true,
+ CharSet = CharSet.Auto)]
+ public static extern uint TrackPopupMenuEx(
+ IntPtr hmenu,
+ TPM flags,
+ int x,
+ int y,
+ IntPtr hwnd,
+ IntPtr lptpm);
+
+ #endregion
+
+ ///
+ /// 获得桌面 Shell
+ ///
+ public static IShellFolder GetDesktopFolder(out IntPtr ppshf)
+ {
+ SHGetDesktopFolder(out ppshf);
+ Object obj = Marshal.GetObjectForIUnknown(ppshf);
+ return (IShellFolder)obj;
+ }
+
+ ///
+ /// 获取显示名称
+ ///
+ public static string GetNameByIShell(IShellFolder Root, IntPtr pidlSub)
+ {
+ IntPtr strr = Marshal.AllocCoTaskMem(MAX_PATH * 2 + 4);
+ Marshal.WriteInt32(strr, 0, 0);
+ StringBuilder buf = new StringBuilder(MAX_PATH);
+ Root.GetDisplayNameOf(pidlSub, SHGNO.INFOLDER, strr);
+ ShellAPI.StrRetToBuf(strr, pidlSub, buf, MAX_PATH);
+ return buf.ToString();
+ }
+
+ ///
+ /// 根据 PIDL 获取显示名称
+ ///
+ public static string GetNameByPIDL(IntPtr pidl)
+ {
+ SHFILEINFO info = new SHFILEINFO();
+ ShellAPI.SHGetFileInfo(pidl, 0, ref info, Marshal.SizeOf(typeof(SHFILEINFO)),
+ SHGFI.PIDL | SHGFI.DISPLAYNAME | SHGFI.TYPENAME);
+ return info.szDisplayName;
+ }
+
+ public static PIDLShellFolder GetPIDLAndParentIShellFolder(string path)
+ {
+
+ if (Directory.Exists(path))
+ {
+ return GetPIDLAndParentIshellFolderForFolder(path);
+ }
+ else if (File.Exists(path))
+ {
+ return GetPIDLAndParentIshellFolderForFile(path);
+ }
+
+ return null;
+ }
+
+ private static PIDLShellFolder GetPIDLAndParentIshellFolderForFolder(string folderPath)
+ {
+ return null;
+ }
+
+ ///
+ /// Get PIDL and parent shellfolder for given file path
+ ///
+ ///
+ ///
+ private static PIDLShellFolder GetPIDLAndParentIshellFolderForFile(string filePath)
+ {
+ //get desktopPtr first
+ IntPtr desktopPtr;
+ IShellFolder desktop = GetDesktopFolder(out desktopPtr);
+
+ string fileName = Path.GetFileName(filePath);
+ IShellFolder parentShellFolder;
+ string FolderPath = Directory.GetParent(filePath).FullName;
+ IntPtr Pidl = IntPtr.Zero;
+ uint i, j = 0;
+ desktop.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, FolderPath, out i, out Pidl, ref j);
+ desktop.BindToObject(Pidl, IntPtr.Zero, ref Guids.IID_IShellFolder, out parentShellFolder);
+ Marshal.ReleaseComObject(desktop);
+
+ IEnumIDList fileEnum = null;
+ IEnumIDList folderEnum = null;
+ IntPtr fileEnumPtr = IntPtr.Zero;
+ IntPtr folderEnumPtr = IntPtr.Zero;
+ IntPtr pidlSub;
+ int celtFetched;
+
+ if (parentShellFolder.EnumObjects(IntPtr.Zero, SHCONTF.NONFOLDERS | SHCONTF.INCLUDEHIDDEN, out folderEnumPtr) == ShellAPI.S_OK)
+ {
+ folderEnum = (IEnumIDList)Marshal.GetObjectForIUnknown(folderEnumPtr);
+ while (folderEnum.Next(1, out pidlSub, out celtFetched) == 0 && celtFetched == ShellAPI.S_FALSE)
+ {
+ string name = ShellAPI.GetNameByPIDL(pidlSub);
+ if (name == fileName)
+ {
+ PIDLShellFolder ps = new PIDLShellFolder { PIDL = pidlSub, ShellFolder = parentShellFolder };
+ Marshal.ReleaseComObject(parentShellFolder);
+ return ps;
+ }
+ }
+ }
+
+ Marshal.ReleaseComObject(parentShellFolder);
+ return null;
+ }
+
+ }
+
+ public class PIDLShellFolder
+ {
+ public IShellFolder ShellFolder { get; set; }
+ public IntPtr PIDL { get; set; }
+ }
+}
diff --git a/Wox/ShellContext/ShellContextMenuManager.cs b/Wox/ShellContext/ShellContextMenuManager.cs
new file mode 100644
index 0000000000..c23652bafc
--- /dev/null
+++ b/Wox/ShellContext/ShellContextMenuManager.cs
@@ -0,0 +1,79 @@
+锘縰sing System;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+
+namespace Wox.ShellContext
+{
+ public class ShellContextMenuManager
+ {
+ public void GetContextMenus(string path)
+ {
+ IntPtr desktopPtr;
+ IShellFolder desktop = ShellAPI.GetDesktopFolder(out desktopPtr);
+
+ IntPtr ownerHwnd =IntPtr.Zero;
+ IShellFolder Root;
+ string FolderPath = Directory.GetParent(path).FullName;
+ IntPtr Pidl = IntPtr.Zero;
+ IShellFolder parent;
+ uint i, j = 0;
+ desktop.ParseDisplayName(ownerHwnd, IntPtr.Zero, FolderPath, out i, out Pidl, ref j);
+ desktop.BindToObject(Pidl, IntPtr.Zero, ref Guids.IID_IShellFolder, out Root);
+ Marshal.ReleaseComObject(desktop);
+
+ IEnumIDList fileEnum = null;
+ IEnumIDList folderEnum = null;
+ IntPtr fileEnumPtr = IntPtr.Zero;
+ IntPtr folderEnumPtr = IntPtr.Zero;
+ IntPtr pidlSub;
+ int celtFetched;
+
+ if (Root.EnumObjects(ownerHwnd, SHCONTF.FOLDERS | SHCONTF.INCLUDEHIDDEN, out fileEnumPtr) == ShellAPI.S_OK)
+ {
+ fileEnum = (IEnumIDList)Marshal.GetObjectForIUnknown(fileEnumPtr);
+ while (fileEnum.Next(1, out pidlSub, out celtFetched) == 0 && celtFetched == ShellAPI.S_FALSE)
+ {
+ string name = ShellAPI.GetNameByPIDL(pidlSub);
+ }
+ }
+
+ if (Root.EnumObjects(ownerHwnd, SHCONTF.NONFOLDERS | SHCONTF.INCLUDEHIDDEN, out folderEnumPtr) == ShellAPI.S_OK)
+ {
+ folderEnum = (IEnumIDList)Marshal.GetObjectForIUnknown(folderEnumPtr);
+ while (folderEnum.Next(1, out pidlSub, out celtFetched) == 0 && celtFetched == ShellAPI.S_FALSE)
+ {
+ string name = ShellAPI.GetNameByPIDL(pidlSub);
+ if (Path.GetFileName(path) == name)
+ {
+ IntPtr PIDL = pidlSub;
+ IShellFolder IParent = Root;
+ IntPtr[] pidls = new IntPtr[1];
+ pidls[0] = PIDL;
+
+ //get IContextMenu interface
+ IntPtr iContextMenuPtr = IntPtr.Zero;
+ iContextMenuPtr = IParent.GetUIObjectOf(IntPtr.Zero, (uint)pidls.Length,
+ pidls, ref Guids.IID_IContextMenu, out iContextMenuPtr);
+ IContextMenu iContextMenu = (IContextMenu)Marshal.GetObjectForIUnknown(iContextMenuPtr);
+
+ IntPtr contextMenu = ShellAPI.CreatePopupMenu();
+ iContextMenu.QueryContextMenu(contextMenu, 0, ShellAPI.CMD_FIRST, ShellAPI.CMD_LAST, CMF.NORMAL | CMF.EXPLORE);
+
+ var menuItemCount = ShellAPI.GetMenuItemCount(contextMenu);
+ for (int k = 0; k < menuItemCount - 1; k++)
+ {
+ StringBuilder menuName = new StringBuilder(0x20);
+ ShellAPI.GetMenuString(contextMenu, i, menuName, 0x20, ShellAPI.MF_BYPOSITION);
+ Debug.WriteLine(menuName.Replace("&",""));
+ ShellAPI.DeleteMenu(contextMenu, i, ShellAPI.MF_BYPOSITION);
+ }
+ }
+ }
+ }
+
+ Marshal.ReleaseComObject(Root);
+ }
+ }
+}
diff --git a/Wox/ShellContext/Structs.cs b/Wox/ShellContext/Structs.cs
new file mode 100644
index 0000000000..00dfae4001
--- /dev/null
+++ b/Wox/ShellContext/Structs.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace Wox.ShellContext
+{
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
+ public struct SHFILEINFO
+ {
+ public IntPtr hIcon;
+ public int iIcon;
+ public SFGAO dwAttributes;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = ShellAPI.MAX_PATH)]
+ public string szDisplayName;
+ [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
+ public string szTypeName;
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
+ public struct CMINVOKECOMMANDINFO
+ {
+ public int cbSize; // sizeof(CMINVOKECOMMANDINFO)
+ public int fMask; // any combination of CMIC_MASK_*
+ public IntPtr hwnd; // might be NULL (indicating no owner window)
+ public IntPtr lpVerb; // either a string or MAKEINTRESOURCE(idOffset)
+ public IntPtr lpParameters; // might be NULL (indicating no parameter)
+ public IntPtr lpDirectory; // might be NULL (indicating no specific directory)
+ public int nShow; // one of SW_ values for ShowWindow() API
+ public int dwHotKey;
+ public IntPtr hIcon;
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
+ public struct CMINVOKECOMMANDINFOEX
+ {
+ public int cbSize;
+ public uint fMask;
+ public IntPtr hwnd;
+ public IntPtr lpVerb;
+ [MarshalAs(UnmanagedType.LPStr)]
+ public string lpParameters;
+ [MarshalAs(UnmanagedType.LPStr)]
+ public string lpDirectory;
+ public int nShow;
+ public int dwHotKey;
+ public IntPtr hIcon;
+ [MarshalAs(UnmanagedType.LPStr)]
+ public string lpTitle;
+ public IntPtr lpVerbW;
+ [MarshalAs(UnmanagedType.LPWStr)]
+ public string lpParametersW;
+ [MarshalAs(UnmanagedType.LPWStr)]
+ public string lpDirectoryW;
+ [MarshalAs(UnmanagedType.LPWStr)]
+ public string lpTitleW;
+ public POINT ptInvoke;
+ }
+
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
+ public struct POINT
+ {
+ public POINT(int x, int y)
+ {
+ this.x = x;
+ this.y = y;
+ }
+
+ public int x;
+ public int y;
+ }
+
+}
diff --git a/Wox/Wox.csproj b/Wox/Wox.csproj
index 8ea87a58e8..19b0992a31 100644
--- a/Wox/Wox.csproj
+++ b/Wox/Wox.csproj
@@ -122,8 +122,15 @@
-
+
+
+
+
+
+
+
+