Exemple #1
0
        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>());
        }
Exemple #2
0
        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>();
                }
            }));
        }
Exemple #3
0
        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));
            }
        }
Exemple #6
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;
                }
            }));
        }