private bool disposedValue = false; // To detect redundant calls protected virtual void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { // TODO: dispose managed state (managed objects). if (Items != null) { foreach (var si in Items) { (si as IDisposable)?.Dispose(); } Items = null; } } // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below. if (hMenu != null) { User32.DestroyMenu(hMenu); hMenu = null; } if (cMenu != null) { Marshal.ReleaseComObject(cMenu); cMenu = null; } disposedValue = true; } }
public static Task <ContextMenuPackage[]> FetchContextMenuItemsAsync(string Path, bool FetchExtensionMenu = false) { IsLastExtendedMenuRequested = FetchExtensionMenu; return(Helper.CreateSTATask(() => { try { if (File.Exists(Path) || Directory.Exists(Path)) { using (ShellItem Item = ShellItem.Open(Path)) { Shell32.IContextMenu ContextObject = Item.GetHandler <Shell32.IContextMenu>(Shell32.BHID.BHID_SFUIObject); using (User32.SafeHMENU Menu = User32.CreatePopupMenu()) { ContextObject.QueryContextMenu(Menu, 0, 0, int.MaxValue, (FetchExtensionMenu ? Shell32.CMF.CMF_EXTENDEDVERBS : Shell32.CMF.CMF_NORMAL) | Shell32.CMF.CMF_SYNCCASCADEMENU).ThrowIfFailed(); return FetchContextMenuCore(ContextObject, Menu); } } } else { return Array.Empty <ContextMenuPackage>(); } } catch { return Array.Empty <ContextMenuPackage>(); } })); }
public ContextMenu(Shell32.IContextMenu cMenu, User32.SafeHMENU hMenu, IEnumerable <string> itemsPath) { this.cMenu = cMenu; this.hMenu = hMenu; this.ItemsPath = itemsPath.ToList(); this.Items = new List <Win32ContextMenuItem>(); }
public static bool InvokeVerb(string Path, string Verb) { try { if (File.Exists(Path) || Directory.Exists(Path)) { using (ShellItem Item = ShellItem.Open(Path)) using (ShellContextMenu ContextMenu = new ShellContextMenu(Item)) { Shell32.CMINVOKECOMMANDINFOEX InvokeCommand = new Shell32.CMINVOKECOMMANDINFOEX { lpVerb = new SafeResourceId(Verb, CharSet.Ansi), nShow = ShowWindowCommand.SW_SHOWNORMAL, cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(Shell32.CMINVOKECOMMANDINFOEX))) }; using (User32.SafeHMENU NewMenu = User32.CreatePopupMenu()) { ContextMenu.ComInterface.QueryContextMenu(NewMenu, 0, 0, ushort.MaxValue, Shell32.CMF.CMF_EXTENDEDVERBS | Shell32.CMF.CMF_EXPLORE | Shell32.CMF.CMF_OPTIMIZEFORINVOKE); ContextMenu.ComInterface.InvokeCommand(InvokeCommand); } } return(true); } else { return(false); } } catch { return(false); } }
public static Task <ContextMenuPackage[]> FetchContextMenuItemsAsync(string[] PathArray, bool IncludeExtensionItem = false) { if (PathArray.Length > 0) { return(Helper.CreateSTATask(() => { try { if (Array.TrueForAll(PathArray, (Path) => File.Exists(Path) || Directory.Exists(Path))) { Shell32.IContextMenu ContextObject = GetContextMenuObject(PathArray); using (User32.SafeHMENU Menu = User32.CreatePopupMenu()) { ContextObject.QueryContextMenu(Menu, 0, 0, Convert.ToUInt32(short.MaxValue), (IncludeExtensionItem ? Shell32.CMF.CMF_EXTENDEDVERBS : Shell32.CMF.CMF_NORMAL) | Shell32.CMF.CMF_SYNCCASCADEMENU).ThrowIfFailed(); return FetchContextMenuCore(ContextObject, Menu, PathArray, IncludeExtensionItem); } } else { return Array.Empty <ContextMenuPackage>(); } } catch { return Array.Empty <ContextMenuPackage>(); } })); } else { return(Task.FromResult(Array.Empty <ContextMenuPackage>())); } }
public static Task <ContextMenuPackage[]> FetchContextMenuItemsAsync(string[] PathArray, bool IncludeExtensionItem = false) { if (PathArray.Length > 0) { return(Helper.ExecuteOnSTAThreadAsync(() => { try { if (Array.TrueForAll(PathArray, (Path) => File.Exists(Path) || Directory.Exists(Path))) { Shell32.IContextMenu ContextObject = GetContextMenuObject(PathArray); if (ContextObject != null) { using (User32.SafeHMENU Menu = User32.CreatePopupMenu()) { if (ContextObject.QueryContextMenu(Menu, 0, 0, 0x7FFF, (IncludeExtensionItem ? Shell32.CMF.CMF_EXTENDEDVERBS : Shell32.CMF.CMF_NORMAL) | Shell32.CMF.CMF_SYNCCASCADEMENU).Succeeded) { return FetchContextMenuCore(ContextObject, Menu, PathArray, IncludeExtensionItem); } else { return Array.Empty <ContextMenuPackage>(); } } } else { return Array.Empty <ContextMenuPackage>(); } } else { return Array.Empty <ContextMenuPackage>(); } } catch { return Array.Empty <ContextMenuPackage>(); } })); } else { return(Task.FromResult(Array.Empty <ContextMenuPackage>())); } }
public static bool InvokeVerb(string Path, string Verb) { try { if (File.Exists(Path) || Directory.Exists(Path)) { using (ShellItem Item = ShellItem.Open(Path)) { Shell32.CMINVOKECOMMANDINFOEX InvokeCommand = new Shell32.CMINVOKECOMMANDINFOEX { lpVerb = new SafeResourceId(Verb, CharSet.Ansi), nShow = ShowWindowCommand.SW_SHOWNORMAL, cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(Shell32.CMINVOKECOMMANDINFOEX))) }; Shell32.IContextMenu Context = Item.GetHandler <Shell32.IContextMenu>(Shell32.BHID.BHID_SFUIObject); using (User32.SafeHMENU NewMenu = User32.CreatePopupMenu()) { try { Context.QueryContextMenu(NewMenu, 0, 0, ushort.MaxValue, Shell32.CMF.CMF_NORMAL | Shell32.CMF.CMF_EXTENDEDVERBS); Context.InvokeCommand(InvokeCommand); } catch { return(false); } finally { Marshal.ReleaseComObject(Context); } } } return(true); } else { return(false); } } catch { return(false); } }
public ContextMenu(Shell32.IContextMenu cMenu, User32.SafeHMENU hMenu) { this.cMenu = cMenu; this.hMenu = hMenu; this.Items = new List <Win32ContextMenuItem>(); }
public static Task <bool> InvokeVerbAsync(string[] RelatedPath, string Verb, int Id, bool IncludeExtensionItem) { if (RelatedPath.Length > 0) { return(Helper.ExecuteOnSTAThreadAsync(() => { try { if (Array.TrueForAll(RelatedPath, (Path) => File.Exists(Path) || Directory.Exists(Path))) { Shell32.IContextMenu ContextObject = GetContextMenuObject(RelatedPath); using (User32.SafeHMENU Menu = User32.CreatePopupMenu()) { if (ContextObject.QueryContextMenu(Menu, 0, 0, 0x7FFF, (IncludeExtensionItem ? Shell32.CMF.CMF_EXTENDEDVERBS : Shell32.CMF.CMF_NORMAL) | Shell32.CMF.CMF_SYNCCASCADEMENU).Succeeded) { if (!string.IsNullOrEmpty(Verb)) { using (SafeResourceId VerbId = new SafeResourceId(Verb)) { Shell32.CMINVOKECOMMANDINFOEX VerbInvokeCommand = new Shell32.CMINVOKECOMMANDINFOEX { lpVerb = VerbId, lpVerbW = Verb, nShow = ShowWindowCommand.SW_SHOWNORMAL, fMask = Shell32.CMIC.CMIC_MASK_FLAG_NO_UI | Shell32.CMIC.CMIC_MASK_UNICODE | Shell32.CMIC.CMIC_MASK_ASYNCOK, cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(Shell32.CMINVOKECOMMANDINFOEX))) }; if (ContextObject.InvokeCommand(VerbInvokeCommand).Succeeded) { return true; } } } using (SafeResourceId ResSID = new SafeResourceId(Id)) { Shell32.CMINVOKECOMMANDINFOEX IdInvokeCommand = new Shell32.CMINVOKECOMMANDINFOEX { lpVerb = ResSID, nShow = ShowWindowCommand.SW_SHOWNORMAL, fMask = Shell32.CMIC.CMIC_MASK_FLAG_NO_UI | Shell32.CMIC.CMIC_MASK_ASYNCOK, cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(Shell32.CMINVOKECOMMANDINFOEX))) }; return ContextObject.InvokeCommand(IdInvokeCommand).Succeeded; } } else { return false; } } } else { return false; } } catch (Exception ex) { LogTracer.Log(ex, "Exception was threw when invoke the context menu item"); return false; } })); } else { return(Task.FromResult(false)); } }
public static List <ContextMenuPackage> FetchContextMenuItems(string Path, bool FetchExtensionMenu = false) { try { if (File.Exists(Path) || Directory.Exists(Path)) { using (ShellItem Item = ShellItem.Open(Path)) { Shell32.IContextMenu Context = Item.GetHandler <Shell32.IContextMenu>(); try { using (User32.SafeHMENU NewMenu = User32.CreatePopupMenu()) { Context.QueryContextMenu(NewMenu, 0, 0, ushort.MaxValue, FetchExtensionMenu ? (Shell32.CMF.CMF_NORMAL | Shell32.CMF.CMF_EXTENDEDVERBS) : Shell32.CMF.CMF_NORMAL); int MaxCount = User32.GetMenuItemCount(NewMenu); List <ContextMenuPackage> ContextMenuItemList = new List <ContextMenuPackage>(MaxCount); for (uint i = 0; i < MaxCount; i++) { IntPtr DataPtr = Marshal.AllocHGlobal(BufferSize); try { User32.MENUITEMINFO Info = new User32.MENUITEMINFO { fMask = User32.MenuItemInfoMask.MIIM_STRING | User32.MenuItemInfoMask.MIIM_ID | User32.MenuItemInfoMask.MIIM_FTYPE | User32.MenuItemInfoMask.MIIM_BITMAP | User32.MenuItemInfoMask.MIIM_STATE, dwTypeData = DataPtr, cch = Convert.ToUInt32(BufferSize - 1), cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(User32.MENUITEMINFO))) }; if (User32.GetMenuItemInfo(NewMenu, i, true, ref Info)) { if (Info.fType.HasFlag(User32.MenuItemType.MFT_STRING) && Info.fState.HasFlag(User32.MenuItemState.MFS_ENABLED)) { IntPtr VerbPtr = Marshal.AllocHGlobal(BufferSize); try { Context.GetCommandString(new IntPtr(Info.wID), Shell32.GCS.GCS_VERBW, IntPtr.Zero, VerbPtr, Convert.ToUInt32(BufferSize - 1)); string Verb = Marshal.PtrToStringUni(VerbPtr); switch (Verb.ToLower()) { case "open": case "opennewprocess": case "pintohome": case "cut": case "copy": case "paste": case "delete": case "properties": case "openas": case "link": case "runas": case "rename": case "{e82bd2a8-8d63-42fd-b1ae-d364c201d8a7}": { break; } default: { IntPtr HelpTextPtr = Marshal.AllocHGlobal(BufferSize); try { Context.GetCommandString(new IntPtr(Info.wID), Shell32.GCS.GCS_HELPTEXTW, IntPtr.Zero, HelpTextPtr, Convert.ToUInt32(BufferSize - 1)); string HelpText = Marshal.PtrToStringUni(HelpTextPtr); if (Info.hbmpItem != HBITMAP.NULL) { using (Bitmap OriginBitmap = Info.hbmpItem.ToBitmap()) { BitmapData OriginData = OriginBitmap.LockBits(new Rectangle(0, 0, OriginBitmap.Width, OriginBitmap.Height), ImageLockMode.ReadOnly, OriginBitmap.PixelFormat); try { using (Bitmap ArgbBitmap = new Bitmap(OriginBitmap.Width, OriginBitmap.Height, OriginData.Stride, PixelFormat.Format32bppArgb, OriginData.Scan0)) using (MemoryStream Stream = new MemoryStream()) { ArgbBitmap.Save(Stream, ImageFormat.Png); ContextMenuItemList.Add(new ContextMenuPackage(HelpText, Verb, Stream.ToArray())); } } finally { OriginBitmap.UnlockBits(OriginData); } } } else { ContextMenuItemList.Add(new ContextMenuPackage(HelpText, Verb, Array.Empty <byte>())); } } finally { Marshal.FreeHGlobal(HelpTextPtr); } break; } } } catch { continue; } finally { Marshal.FreeHGlobal(VerbPtr); } } } } finally { Marshal.FreeHGlobal(DataPtr); } } return(ContextMenuItemList); } } finally { Marshal.ReleaseComObject(Context); } } } else { return(new List <ContextMenuPackage>(0)); } } catch { return(new List <ContextMenuPackage>(0)); } }
public static List <(string, string, string)> FetchContextMenuItems(IEnumerable <string> Path, bool FetchExtensionMenu = false) { ShellItem[] ItemCollecion = Array.Empty <ShellItem>(); try { ItemCollecion = Path.Where((Item) => File.Exists(Item) || Directory.Exists(Item)).Select((Item) => ShellItem.Open(Item)).ToArray(); Context = new ShellContextMenu(ItemCollecion); using (User32.SafeHMENU NewMenu = User32.CreatePopupMenu()) { Context.ComInterface.QueryContextMenu(NewMenu, 0, 0, ushort.MaxValue, FetchExtensionMenu ? (Shell32.CMF.CMF_VERBSONLY | Shell32.CMF.CMF_EXTENDEDVERBS) : Shell32.CMF.CMF_VERBSONLY); int MaxCount = User32.GetMenuItemCount(NewMenu); List <(string, string, string)> ContextMenuItemList = new List <(string, string, string)>(MaxCount); for (uint i = 0; i < MaxCount; i++) { IntPtr DataPtr = Marshal.AllocHGlobal(BufferSize); try { User32.MENUITEMINFO Info = new User32.MENUITEMINFO { fMask = User32.MenuItemInfoMask.MIIM_STRING | User32.MenuItemInfoMask.MIIM_ID | User32.MenuItemInfoMask.MIIM_FTYPE | User32.MenuItemInfoMask.MIIM_BITMAP | User32.MenuItemInfoMask.MIIM_STATE, dwTypeData = DataPtr, cch = Convert.ToUInt32(BufferSize - 1), cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(User32.MENUITEMINFO))) }; if (User32.GetMenuItemInfo(NewMenu, i, true, ref Info)) { if (Info.fType == User32.MenuItemType.MFT_STRING && Info.fState == User32.MenuItemState.MFS_ENABLED) { IntPtr VerbPtr = Marshal.AllocHGlobal(BufferSize); try { Context.ComInterface.GetCommandString(new IntPtr(Info.wID), Shell32.GCS.GCS_VERBW, IntPtr.Zero, VerbPtr, Convert.ToUInt32(BufferSize - 1)); string Verb = Marshal.PtrToStringUni(VerbPtr); switch (Verb.ToLower()) { case "open": case "opennewprocess": case "pintohome": case "cut": case "copy": case "paste": case "delete": case "properties": case "openas": case "link": case "runas": case "rename": { break; } default: { IntPtr HelpTextPtr = Marshal.AllocHGlobal(BufferSize); try { Context.ComInterface.GetCommandString(new IntPtr(Info.wID), Shell32.GCS.GCS_HELPTEXTW, IntPtr.Zero, HelpTextPtr, Convert.ToUInt32(BufferSize - 1)); string HelpText = Marshal.PtrToStringUni(HelpTextPtr); if (Info.hbmpItem != HBITMAP.NULL) { using (MemoryStream Stream = new MemoryStream()) { Bitmap OriginBitmap = Info.hbmpItem.ToBitmap(); BitmapData OriginData = OriginBitmap.LockBits(new Rectangle(0, 0, OriginBitmap.Width, OriginBitmap.Height), ImageLockMode.ReadOnly, OriginBitmap.PixelFormat); Bitmap ArgbBitmap = new Bitmap(OriginBitmap.Width, OriginBitmap.Height, OriginData.Stride, PixelFormat.Format32bppArgb, OriginData.Scan0); ArgbBitmap.Save(Stream, ImageFormat.Png); ContextMenuItemList.Add((HelpText, Verb, Convert.ToBase64String(Stream.ToArray()))); } } else { ContextMenuItemList.Add((HelpText, Verb, string.Empty)); } } finally { Marshal.FreeHGlobal(HelpTextPtr); } break; } } } catch { continue; } finally { Marshal.FreeHGlobal(VerbPtr); } } } } finally { Marshal.FreeHGlobal(DataPtr); } } return(ContextMenuItemList); } } catch { return(new List <(string, string, string)>(0)); } finally { Array.ForEach(ItemCollecion, (Item) => Item.Dispose()); } }
public static Task <bool> InvokeVerbAsync(string Path, string Verb, int Id) { return(Helper.CreateSTATask(() => { try { if (File.Exists(Path) || Directory.Exists(Path)) { using (ShellItem Item = ShellItem.Open(Path)) { Shell32.IContextMenu ContextObject = Item.GetHandler <Shell32.IContextMenu>(Shell32.BHID.BHID_SFUIObject); using (User32.SafeHMENU Menu = User32.CreatePopupMenu()) { ContextObject.QueryContextMenu(Menu, 0, 0, int.MaxValue, (IsLastExtendedMenuRequested ? Shell32.CMF.CMF_EXTENDEDVERBS : Shell32.CMF.CMF_NORMAL) | Shell32.CMF.CMF_SYNCCASCADEMENU).ThrowIfFailed(); if (string.IsNullOrEmpty(Verb)) { using (SafeResourceId ResSID = new SafeResourceId(Id)) { Shell32.CMINVOKECOMMANDINFOEX IdInvokeCommand = new Shell32.CMINVOKECOMMANDINFOEX { lpVerb = ResSID, nShow = ShowWindowCommand.SW_SHOWNORMAL, fMask = Shell32.CMIC.CMIC_MASK_FLAG_NO_UI, cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(Shell32.CMINVOKECOMMANDINFOEX))) }; return ContextObject.InvokeCommand(IdInvokeCommand).Succeeded; } } else { using (SafeResourceId VerbSID = new SafeResourceId(Verb, CharSet.Ansi)) { Shell32.CMINVOKECOMMANDINFOEX VerbInvokeCommand = new Shell32.CMINVOKECOMMANDINFOEX { lpVerb = VerbSID, lpVerbW = Verb, nShow = ShowWindowCommand.SW_SHOWNORMAL, fMask = Shell32.CMIC.CMIC_MASK_FLAG_NO_UI, cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(Shell32.CMINVOKECOMMANDINFOEX))) }; if (ContextObject.InvokeCommand(VerbInvokeCommand).Failed) { using (SafeResourceId ResSID = new SafeResourceId(Id)) { Shell32.CMINVOKECOMMANDINFOEX IdInvokeCommand = new Shell32.CMINVOKECOMMANDINFOEX { lpVerb = ResSID, nShow = ShowWindowCommand.SW_SHOWNORMAL, fMask = Shell32.CMIC.CMIC_MASK_FLAG_NO_UI, cbSize = Convert.ToUInt32(Marshal.SizeOf(typeof(Shell32.CMINVOKECOMMANDINFOEX))) }; return ContextObject.InvokeCommand(IdInvokeCommand).Succeeded; } } else { return true; } } } } } } else { return false; } } catch { return false; } })); }