Example #1
0
        private void Enumerate()
        {
            IntPtr hEnum = IntPtr.Zero;

            Files.Clear();

            try
            {
                if (ShellFolderInterface?.EnumObjects(_hwndInput, SHCONTF.FOLDERS | SHCONTF.NONFOLDERS,
                                                      out hEnum) == NativeMethods.S_OK)
                {
                    try
                    {
                        IEnumIDList enumIdList =
                            (IEnumIDList)Marshal.GetTypedObjectForIUnknown(hEnum, typeof(IEnumIDList));

                        while (enumIdList.Next(1, out var pidlChild, out var numFetched) == NativeMethods.S_OK && numFetched == 1)
                        {
                            if (_isDisposed)
                            {
                                break;
                            }

                            AddFile(pidlChild);
                        }

                        Marshal.FinalReleaseComObject(enumIdList);
                    }
                    catch (Exception e)
                    {
                        ShellLogger.Error($"ShellFolder: Exception while enumerating IShellFolder: {e.Message}");
                    }
                    finally
                    {
                        Marshal.Release(hEnum);
                    }
                }
                else
                {
                    ShellLogger.Error($"ShellFolder: Unable to enumerate IShellFolder");
                }
            }
            catch (Exception e)
            {
                ShellLogger.Error($"ShellFolder: Unable to enumerate IShellFolder: {e.Message}");
            }
        }
Example #2
0
        /// <summary>
        /// Gets the children.
        /// </summary>
        /// <param name="childTypes">The child types.</param>
        /// <returns>
        /// The children.
        /// </returns>
        public IEnumerable <ShellItem> GetChildren(ChildTypes childTypes)
        {
            //  We'll return a list of children.
            var children = new List <ShellItem>();

            //  Create the enum flags from the childtypes.
            SHCONTF enumFlags = 0;

            if (childTypes.HasFlag(ChildTypes.Folders))
            {
                enumFlags |= SHCONTF.SHCONTF_FOLDERS;
            }
            if (childTypes.HasFlag(ChildTypes.Files))
            {
                enumFlags |= SHCONTF.SHCONTF_NONFOLDERS;
            }
            if (childTypes.HasFlag(ChildTypes.Hidden))
            {
                enumFlags |= SHCONTF.SHCONTF_INCLUDEHIDDEN;
            }

            try
            {
                //  Create an enumerator for the children.
                IEnumIDList pEnum;
                var         result = ShellFolderInterface.EnumObjects(IntPtr.Zero, enumFlags, out pEnum);

                //  Validate the result.
                if (result != 0)
                {
                    //  Throw the failure as an exception.
                    Marshal.ThrowExceptionForHR((int)result);
                }

                // TODO: This logic should go in the pidl manager.

                //  Enumerate the children, ten at a time.
                const int batchSize = 10;
                var       pidlArray = Marshal.AllocCoTaskMem(IntPtr.Size * 10);
                uint      itemsFetched;
                result = WinError.S_OK;
                do
                {
                    result = pEnum.Next(batchSize, pidlArray, out itemsFetched);

                    //  Get each pidl.
                    var pidls = new IntPtr[itemsFetched];
                    Marshal.Copy(pidlArray, pidls, 0, (int)itemsFetched);
                    foreach (var childPidl in pidls)
                    {
                        //  Create a new shell folder.
                        var childShellFolder = new ShellItem();

                        //  Initialize it.
                        try
                        {
                            childShellFolder.Initialise(childPidl, this);
                        }
                        catch (Exception exception)
                        {
                            throw new InvalidOperationException("Failed to initialise child.", exception);
                        }

                        //  Add the child.
                        children.Add(childShellFolder);

                        //  Free the PIDL, reset the result.
                        Marshal.FreeCoTaskMem(childPidl);
                    }
                } while (result == WinError.S_OK);

                Marshal.FreeCoTaskMem(pidlArray);

                //  Release the enumerator.
                if (Marshal.IsComObject(pEnum))
                {
                    Marshal.ReleaseComObject(pEnum);
                }
            }
            catch (Exception exception)
            {
                throw new InvalidOperationException("Failed to enumerate children.", exception);
            }

            //  Sort the children.
            var sortedChildren = children.Where(c => c.IsFolder).ToList();

            sortedChildren.AddRange(children.Where(c => !c.IsFolder));

            //  Return the children.
            return(sortedChildren);
        }
Example #3
0
        /// <summary>
        /// Gets the children.
        /// </summary>
        /// <param name="childTypes">The child types.</param>
        /// <returns>
        /// The children.
        /// </returns>
        public IEnumerable <ShellItem> GetChildren(ChildTypes childTypes)
        {
            //  We'll return a list of children.
            var children = new List <ShellItem>();

            //  Create the enum flags from the childtypes.
            SHCONTF enumFlags = SHCONTF.None;

            if (childTypes.HasFlag(ChildTypes.Folders))
            {
                enumFlags |= SHCONTF.SHCONTF_FOLDERS;
            }
            if (childTypes.HasFlag(ChildTypes.Files))
            {
                enumFlags |= SHCONTF.SHCONTF_NONFOLDERS;
            }
            if (childTypes.HasFlag(ChildTypes.Hidden))
            {
                enumFlags |= SHCONTF.SHCONTF_INCLUDEHIDDEN;
            }

            try
            {
                //  Create an enumerator for the children.
                IEnumIDList pEnum;
                var         result = ShellFolderInterface.EnumObjects(IntPtr.Zero, enumFlags, out pEnum);

                //  Validate the result.
                if (result != 0)
                {
                    //  Throw the failure as an exception.
                    Marshal.ThrowExceptionForHR((int)result);
                }

                //  Start going through children.
                IntPtr childPIDL;
                int    enumResult;
                pEnum.Next(1, out childPIDL, out enumResult);

                //  Now start enumerating.
                while (childPIDL != IntPtr.Zero && enumResult == 1)
                {
                    //  Create a new shell folder.
                    var childShellFolder = new ShellItem();

                    //  Initialize it.
                    try
                    {
                        childShellFolder.Initialise(childPIDL, this);
                    }
                    catch (Exception exception)
                    {
                        throw new InvalidOperationException("Failed to initialise child.", exception);
                    }

                    //  Add the child.
                    children.Add(childShellFolder);

                    //  Free the PIDL, reset the result.
                    Marshal.FreeCoTaskMem(childPIDL);

                    //  Move onwards.
                    pEnum.Next(1, out childPIDL, out enumResult);
                }

                //  Release the enumerator.
                Marshal.ReleaseComObject(pEnum);
            }
            catch (Exception exception)
            {
                throw new InvalidOperationException("Failed to enumerate children.", exception);
            }

            //  Sort the children.
            var sortedChildren = children.Where(c => c.IsFolder).ToList();

            sortedChildren.AddRange(children.Where(c => !c.IsFolder));

            //  Return the children.
            return(sortedChildren);
        }