/// <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); }
/// <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); }
//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); }
/// <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; }