예제 #1
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);
        }
예제 #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 = 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);
        }
예제 #3
0
        //public static int CreateViewObject(IShellFolder2 folder, IntPtr Handle, ref Guid shellViewGuid, out IntPtr iShellViewPtr)
        //{
        //    folder.CreateViewObject
        //}

        public static IEnumerable <ShellItem> GetChildren(this ShellItem parent, ChildTypes childTypes, bool lThrow = true)
        {
            //  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;

                //enumFlags |= SHCONTF.SHCONTF_NAVIGATION_ENUM
                //    | SHCONTF.SHCONTF_FASTITEMS // The calling application is looking for resources that can be enumerated quickly.
                //    | SHCONTF.SHCONTF_FLATLIST; // Enumerate items as a simple list even if the folder itself is not structured in that way
            }
            if (childTypes.HasFlag(ChildTypes.Hidden))
            {
                enumFlags |= SHCONTF.SHCONTF_INCLUDEHIDDEN;
            }
            //| SHCONTF.SHCONTF_INCLUDESUPERHIDDEN;

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

                //  Validate the result.
                if (result != 0)
                {
                    if (!lThrow)
                    {
                        return(Enumerable.Empty <ShellItem>());
                    }

                    //  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, parent);
                        }
                        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);
        }
예제 #4
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;
        }