public void GetHandlerTest() { using var i = new ShellItem(testDoc); var ps = i.GetHandler <PropSys.IPropertyStore>(BHID.BHID_PropertyStore); Assert.That(ps, Is.Not.Null.And.InstanceOf <PropSys.IPropertyStore>()); System.Runtime.InteropServices.Marshal.ReleaseComObject(ps); ps = i.GetHandler <PropSys.IPropertyStore>(); Assert.That(ps, Is.Not.Null.And.InstanceOf <PropSys.IPropertyStore>()); System.Runtime.InteropServices.Marshal.ReleaseComObject(ps); Assert.That(() => i.GetHandler <IExtractIcon>(), Throws.TypeOf <ArgumentOutOfRangeException>()); }
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>(); } })); }
private static Shell32.IContextMenu GetContextMenuObject(params string[] PathArray) { if (PathArray.Count() > 1) { ShellItem[] Items = PathArray.Select((Path) => new ShellItem(Path)).ToArray(); ShellFolder[] ParentFolders = Items.Select((Item) => Item.Parent).ToArray(); try { if (ParentFolders.Skip(1).All((Folder) => Folder == ParentFolders[0])) { return(ParentFolders[0].GetChildrenUIObjects <Shell32.IContextMenu>(null, Items)); } else { throw new ArgumentException("All items must have the same parent"); } } finally { Array.ForEach(Items, (It) => It.Dispose()); Array.ForEach(ParentFolders, (It) => It.Dispose()); } } else { using (ShellItem Item = new ShellItem(PathArray.First())) { if (Item is ShellFolder Folder) { return(Folder.IShellFolder.CreateViewObject <Shell32.IContextMenu>(HWND.NULL)); } else { if (Item.Parent is ShellFolder ParentFolder) { try { return(ParentFolder.GetChildrenUIObjects <Shell32.IContextMenu>(null, Item)); } finally { ParentFolder?.Dispose(); } } else { return(Item.GetHandler <Shell32.IContextMenu>(Shell32.BHID.BHID_SFUIObject)); } } } } }
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 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 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; } })); }