示例#1
0
        /// <summary>
        /// Rename a file or folder in an directory.
        /// </summary>
        public static void Rename(string source, string destName)
        {
            //DirectoryInfoEx srcDir = new DirectoryInfoEx(Path.GetDirectoryName(source));
            FileSystemInfoEx srcElement = new FileSystemInfoEx(source);
            string           srcName    = Path.GetFileName(source);

            if (!srcElement.Exists || srcElement.Parent == null)
            {
                throw new IOException("Source not exists");
            }

            //0.15: Fixed ShellFolder not freed.
            using (ShellFolder2 srcParentShellFolder = srcElement.Parent.ShellFolder)
            {
                if (srcParentShellFolder == null)
                {
                    throw new IOException("Source directory does not support IShellFolder");
                }

                IntPtr tmpPtr;
                int    hr = srcParentShellFolder.SetNameOf(IntPtr.Zero, srcElement.PIDLRel.Ptr,
                                                           destName, ShellAPI.SHGNO.FORPARSING, out tmpPtr);

                PIDL tmpPIDL = new PIDL(tmpPtr, false); //consume the IntPtr, and free it.
                tmpPIDL.Free();

                if (hr != ShellAPI.S_OK)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }
            }
        }
示例#2
0
        //0.12: Fixed PIDL, PIDLRel, ShellFolder, Storage properties generated on demand to avoid x-thread issues.
        internal PIDL getRelPIDL()
        {
            if (_pidlRel != null)
            {
                //0.14 : FileSystemInfoEx now stored a copy of PIDL/Rel, will return copy of it when properties is called (to avoid AccessViolation).
                return(new PIDL(_pidlRel, true));
            }


            //0.16: Fixed getRelPIDL() cannot return correct value if File/DirInfoEx construct with string. (attemp to return a freed up pointer).
            PIDL pidlLookup = getPIDL();

            try
            {
                return(getRelativePIDL(pidlLookup));
            }
            finally
            {
                if (pidlLookup != null)
                {
                    pidlLookup.Free();
                }
                pidlLookup = null;
            }
        }
示例#3
0
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            try
            {
                if (value is FileSystemInfoEx)
                {
                    PIDL pidlLookup = (value as FileSystemInfoEx).PIDL;
                    try
                    {
                        Icon ico = GetFileIcon(pidlLookup.Ptr);
                        return(ico != null?loadBitmap(ico.ToBitmap()) : null);
                    }
                    finally
                    {
                        if (pidlLookup != null)
                        {
                            pidlLookup.Free();
                        }
                        pidlLookup = null;
                    }
                }
            }
            catch
            {
            }

            return(null);
        }
示例#4
0
        //internal static string getParentParseName(PIDL pidl)
        //{
        //    PIDL relPIDL;
        //    PIDL parentPIDL = getParentPIDL(pidl, out relPIDL);
        //    IShellFolder sf = getParentIShellFolder(parentPIDL, out relPIDL);
        //    if (relPIDL.Size == 0)
        //        return IOTools.IID_Desktop;
        //    return loadName(sf, relPIDL, ShellAPI.SHGNO.FORPARSING);
        //}

        internal static ShellFolder2 getParentIShellFolder(PIDL pidl, out PIDL relPIDL)
        {
            int    hr;
            IntPtr ptrShellFolder = IntPtr.Zero;

            if (pidl.Size == 0 || PIDL.ILFindLastID(pidl.Ptr) == pidl.Ptr || //is root or parent is root
                PIDLToPath(pidl) == Environment.GetFolderPath(Environment.SpecialFolder.Desktop))
            {
                hr      = ShellAPI.SHGetDesktopFolder(out ptrShellFolder);
                relPIDL = new PIDL(pidl, true);
            }
            else
            {
                PIDL parentPIDL = getParentPIDL(pidl, out relPIDL);

                //Console.WriteLine("ParentPIDL.Size = {0}", parentPIDL.Size);
                Guid guid = ShellAPI.IID_IShellFolder2;
                using (ShellFolder2 _desktopShellFolder = getDesktopShellFolder())
                    hr = _desktopShellFolder.BindToObject(parentPIDL.Ptr, IntPtr.Zero,
                                                          ref guid, out ptrShellFolder);

                if (parentPIDL != null)
                {
                    parentPIDL.Free();
                }
            }

            if (hr == ShellAPI.S_OK && ptrShellFolder != IntPtr.Zero)
            {
                return(new ShellFolder2(ptrShellFolder));
            }
            Marshal.ThrowExceptionForHR(hr);

            return(null); //mute error.
        }
示例#5
0
 internal FileInfoEx(PIDL fullPIDL, bool freeFullPIDL)
 {
     init(fullPIDL);
     checkProperties();
     if (freeFullPIDL)
     {
         fullPIDL.Free();
     }
 }
        public static bool GetNewContextMenu(ShellItem item, out IntPtr iContextMenuPtr, out IContextMenu iContextMenu)
        {
            if (ShellAPI.CoCreateInstance(
                    ref ShellAPI.CLSID_NewMenu,
                    IntPtr.Zero,
                    ShellAPI.CLSCTX.INPROC_SERVER,
                    ref ShellAPI.IID_IContextMenu,
                    out iContextMenuPtr) == ShellAPI.S_OK)
            {
                iContextMenu = Marshal.GetTypedObjectForIUnknown(iContextMenuPtr, typeof(IContextMenu)) as IContextMenu;

                IntPtr iShellExtInitPtr;
                if (Marshal.QueryInterface(
                        iContextMenuPtr,
                        ref ShellAPI.IID_IShellExtInit,
                        out iShellExtInitPtr) == ShellAPI.S_OK)
                {
                    IShellExtInit iShellExtInit = Marshal.GetTypedObjectForIUnknown(
                        iShellExtInitPtr, typeof(IShellExtInit)) as IShellExtInit;

                    PIDL pidlFull = item.PIDLFull;
                    iShellExtInit.Initialize(pidlFull.Ptr, IntPtr.Zero, 0);

                    Marshal.ReleaseComObject(iShellExtInit);
                    Marshal.Release(iShellExtInitPtr);
                    pidlFull.Free();

                    return(true);
                }
                else
                {
                    if (iContextMenu != null)
                    {
                        Marshal.ReleaseComObject(iContextMenu);
                        iContextMenu = null;
                    }

                    if (iContextMenuPtr != IntPtr.Zero)
                    {
                        Marshal.Release(iContextMenuPtr);
                        iContextMenuPtr = IntPtr.Zero;
                    }

                    return(false);
                }
            }
            else
            {
                iContextMenuPtr = IntPtr.Zero;
                iContextMenu    = null;
                return(false);
            }
        }
示例#7
0
        /// <summary>
        /// Take a directory and return the IStorage PTr interface.
        /// </summary>
        internal static bool getIStorage(DirectoryInfoEx dir, out IntPtr storagePtr)
        {
            //0.19 Fixed ArgumentException when getting storage of C:\{User}\Desktop.
            if (dir.FullName.Equals(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)))
            {
                dir = DirectoryInfoEx.DesktopDirectory;
            }

            //0.15 : Fixed PIDL not freed correctly.
            PIDL dirPIDLRel = dir.PIDLRel;
            int  hr;

            try
            {
                if (dirPIDLRel.Size == 0)
                {
                    IntPtr pidlLast = IntPtr.Zero;
                    hr = ShellAPI.SHBindToParent(dirPIDLRel.Ptr, ShellAPI.IID_IStorage,
                                                 out storagePtr, ref pidlLast);
                }
                else
                {
                    //0.15: Fixed ShellFolder not freed correctly.
                    using (ShellFolder2 dirParentShellFolder = dir.Parent.ShellFolder)
                        if (dirParentShellFolder != null)
                        {
                            hr = dirParentShellFolder.BindToStorage(
                                dirPIDLRel.Ptr, IntPtr.Zero, ref ShellAPI.IID_IStorage,
                                out storagePtr);
                        }
                        else
                        {
                            storagePtr = IntPtr.Zero;
                            return(false);
                        }
                }

                if ((hr != ShellAPI.S_OK))
                {
                    storagePtr = IntPtr.Zero;
                    Marshal.ThrowExceptionForHR(hr);
                    return(false);
                }
            }
            finally { if (dirPIDLRel != null)
                      {
                          dirPIDLRel.Free();
                      }
                      dirPIDLRel = null; }

            return(true);
        }
示例#8
0
        public static T RequestRelativePIDL <T>(this FileSystemInfoEx fsi, Func <PIDL, T> relPidlFuncOnly)
        {
            PIDL relPidl = fsi.getRelPIDL();

            try
            {
                return(relPidlFuncOnly(relPidl));
            }
            finally
            {
                relPidl.Free();
            }
        }
示例#9
0
        public static void RequestPIDL(this FileSystemInfoEx fsi, Action <PIDL> pidlFuncOnly)
        {
            PIDL pidl = fsi.getPIDL();

            try
            {
                pidlFuncOnly(pidl);
            }
            finally
            {
                pidl.Free();
            }
        }
示例#10
0
        public static T RequestPIDL <T>(this FileSystemInfoEx fsi, Func <PIDL, T> pidlFuncOnly)
        {
            PIDL pidl = fsi.getPIDL();

            try
            {
                return(pidlFuncOnly(pidl));
            }
            finally
            {
                pidl.Free();
            }
        }
示例#11
0
        public static void RequestRelativePIDL(this FileSystemInfoEx fsi, Action <PIDL> relPidlFuncOnly)
        {
            PIDL relPidl = fsi.getRelPIDL();

            try
            {
                relPidlFuncOnly(relPidl);
            }
            finally
            {
                relPidl.Free();
            }
        }
示例#12
0
        internal static PIDL getParentPIDL(PIDL pidl)
        {
            PIDL relPIDL = null;

            try
            {
                return(getParentPIDL(pidl, out relPIDL));
            }
            finally { if (relPIDL != null)
                      {
                          relPIDL.Free();
                      }
            }
        }
示例#13
0
        /// <summary>
        /// Gets the path to the system special folder identified by the specified enumeration.
        /// </summary>
        public static string GetFolderPath(ShellAPI.CSIDL folder)
        {
            PIDL pidlLookup = CSIDLtoPIDL(folder);

            try
            {
                return(FileSystemInfoEx.PIDLToPath(pidlLookup));
            }
            finally { if (pidlLookup != null)
                      {
                          pidlLookup.Free();
                      }
            }
        }
示例#14
0
        public static void RequestPIDL(this FileSystemInfoEx fsi, Action <PIDL, PIDL> pidlAndRelPidlFunc)
        {
            PIDL pidl    = fsi.getPIDL();
            PIDL relPidl = fsi.getRelPIDL();

            try
            {
                pidlAndRelPidlFunc(pidl, relPidl);
            }
            finally
            {
                pidl.Free();
                relPidl.Free();
            }
        }
示例#15
0
        public static T RequestPIDL <T>(this FileSystemInfoEx fsi, Func <PIDL, PIDL, T> pidlAndRelPidlFunc)
        {
            PIDL pidl    = fsi.getPIDL();
            PIDL relPidl = fsi.getRelPIDL();

            try
            {
                return(pidlAndRelPidlFunc(pidl, relPidl));
            }
            finally
            {
                pidl.Free();
                relPidl.Free();
            }
        }
 public static bool GetIExtractImage(
     FileInfoEx file,
     out IntPtr iExtractImagePtr,
     out IExtractImage iExtractImage)
 {
     using (ShellFolder2 sf2 = file.Parent.ShellFolder)
     {
         PIDL filePIDL = file.PIDLRel;
         try
         {
             return(GetIExtractImage(sf2, filePIDL.Ptr, out iExtractImagePtr, out iExtractImage));
         }
         finally { filePIDL.Free(); }
     }
 }
        internal static string PIDLToPath(PIDL pidlFull)
        {
            PIDL desktopPIDL = DirectoryInfoEx.DesktopDirectory.PIDL;

            if (pidlFull.Equals(desktopPIDL))
            {
                return("::{00021400-0000-0000-C000-000000000046}");
            }
            if (desktopPIDL != null)
            {
                desktopPIDL.Free();
            }
            desktopPIDL = null;

            using (ShellFolder2 _desktopShellFolder = getDesktopShellFolder())
                return(loadName(_desktopShellFolder, pidlFull, ShellAPI.SHGNO.FORPARSING));
        }
示例#18
0
        internal DirectoryInfoEx(DirectoryInfoEx parentDir, PIDL relPIDL)
        {
            Parent = parentDir;
            PIDL parentPIDL = parentDir.PIDL;

            try
            {
                //0.15: Fixed ShellFolder not freed.
                using (ShellFolder2 parentShellFolder = parentDir.ShellFolder)
                    init(parentShellFolder, parentPIDL, relPIDL);
            }
            finally { if (parentPIDL != null)
                      {
                          parentPIDL.Free();
                      }
                      parentPIDL = null; }
        }
示例#19
0
        private ShellFolder2 getIShellFolder()
        {
            if (this.FullName.Equals(IOTools.IID_Desktop))
            {
                return(getDesktopShellFolder());
            }
            else
            {
                ShellFolder2 retVal = getIShellFolderFromParent();
                if (retVal != null)
                {
                    return(retVal);
                }

                PIDL pidlLookup = PIDL;
                PIDL relPIDL    = this.PIDLRel;
                try
                {
                    using (ShellFolder2 parentShellFolder = getParentIShellFolder(pidlLookup, out relPIDL))
                    {
                        IntPtr ptrShellFolder;
                        int    hr = parentShellFolder.BindToObject(relPIDL.Ptr, IntPtr.Zero, ref ShellAPI.IID_IShellFolder2,
                                                                   out ptrShellFolder);
                        if (ptrShellFolder == IntPtr.Zero || hr != ShellAPI.S_OK)
                        {
                            Marshal.ThrowExceptionForHR(hr);
                        }
                        return(new ShellFolder2(ptrShellFolder));
                    }
                }
                finally
                {
                    if (pidlLookup != null)
                    {
                        pidlLookup.Free();
                    }
                    if (relPIDL != null)
                    {
                        relPIDL.Free();
                    }
                    relPIDL    = null;
                    pidlLookup = null;
                }
            }
        }
示例#20
0
        internal FileInfoEx(IShellFolder2 parentShellFolder, DirectoryInfoEx parentDir, PIDL relPIDL)
        {
            Parent = parentDir;
            PIDL parentPIDL = parentDir.PIDL;

            try
            {
                init(parentShellFolder, parentPIDL, relPIDL);
            }
            finally
            {
                if (parentPIDL != null)
                {
                    parentPIDL.Free();
                }
                parentPIDL = null;
            }
        }
示例#21
0
        public DirectoryInfoEx(ShellAPI.CSIDL csidl)
        {
            PIDL pidlLookup = CSIDLtoPIDL(csidl);

            try
            {
                init(pidlLookup);
                checkProperties();
            }
            finally
            {
                if (pidlLookup != null)
                {
                    pidlLookup.Free();
                }
                pidlLookup = null;
            }
        }
示例#22
0
        public DirectoryInfoEx(Environment.SpecialFolder shellFolder)
        {
            PIDL pidlLookup = CSIDLtoPIDL(IOTools.ShellFolderToCSIDL(shellFolder));

            try
            {
                init(pidlLookup);
                checkProperties();
            }
            finally
            {
                if (pidlLookup != null)
                {
                    pidlLookup.Free();
                }
                pidlLookup = null;
            }
        }
示例#23
0
        public void Dispose()
        {
            if (_pidlRel != null || _pidl != null)
            {
                Threading.Interlocked.Decrement(ref counter);
            }

            if (_pidlRel != null)
            {
                _pidlRel.Free();
            }
            if (_pidl != null)
            {
                _pidl.Free();
            }
            _pidlRel = null;
            _pidl    = null;
        }
示例#24
0
 private bool getExists()
 {
     if (FullName == "::{00021400-0000-0000-C000-000000000046}") //Desktop
     {
         return(true);
     }
     else if (FullName == null)
     {
         return(false);
     }
     else
     {
         try
         {
             if (_pidl != null)
             {
                 using (ShellFolder2 _desktopShellFolder = getDesktopShellFolder())
                     loadName(_desktopShellFolder, _pidl, ShellAPI.SHGNO.FORPARSING);
                 return(true);
             }
             else
             {
                 PIDL pidlLookup = PathToPIDL(FullName);
                 try
                 {
                     return(pidlLookup != null);
                 }
                 finally { if (pidlLookup != null)
                           {
                               pidlLookup.Free();
                           }
                 }
             }
         }
         catch (FileNotFoundException)
         {
             return(false);
         }
     }
 }
示例#25
0
        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            if (m.Msg == (int)ShellAPI.WM.SH_NOTIFY)
            {
                ShellAPI.SHNOTIFYSTRUCT shNotify =
                    (ShellAPI.SHNOTIFYSTRUCT)Marshal.PtrToStructure(m.WParam, typeof(ShellAPI.SHNOTIFYSTRUCT));
                if (this.OnEvent != null)
                {
                    PIDL pidl1 = (!PIDL.IsEmpty(shNotify.dwItem1)) ? new PIDL(shNotify.dwItem1, true) : null;
                    PIDL pidl2 = (!PIDL.IsEmpty(shNotify.dwItem2)) ? new PIDL(shNotify.dwItem2, true) : null;
                    OnEvent(this, new ShellChangeEventArgs(((ShellAPI.SHCNE)m.LParam), pidl1, pidl2));

                    if (pidl1 != null)
                    {
                        pidl1.Free();
                    }
                    if (pidl2 != null)
                    {
                        pidl2.Free();
                    }
                }
            }
        }
        public static object GetProperty(ShellFolder2 sf2, FileInfoEx file, ref PropertyKey propKey)
        {
            PIDL pidlLookup = file.PIDLRel;

            if (pidlLookup != null)
            {
                try
                {
                    object retVal;
                    int    hr = sf2.GetDetailsEx(pidlLookup.Ptr, ref propKey, out retVal);
                    if (hr != ShellAPI.S_OK)
                    {
                        Marshal.ThrowExceptionForHR(hr);
                    }

                    return(retVal);
                }
                finally
                {
                    pidlLookup.Free();
                }
            }
            return(null);
        }
示例#27
0
        //0.17: Added DirectoryInfoEx.EnumerateFiles/EnumerateDirectories/EnumerateFileSystemInfos() methods which work similar as the one in .Net4
        public IEnumerable <FileInfoEx> EnumerateFiles(String searchPattern, SearchOption searchOption, CancelDelegate cancel)
        {
            IntPtr      ptrEnum    = IntPtr.Zero;
            IEnumIDList IEnum      = null;
            PIDL        parentPIDL = this.PIDL;

            using (ShellFolder2 sf = this.ShellFolder)
                try
                {
                    if (sf.EnumObjects(IntPtr.Zero, flag, out ptrEnum) == ShellAPI.S_OK)
                    {
                        IEnum = (IEnumIDList)Marshal.GetTypedObjectForIUnknown(ptrEnum, typeof(IEnumIDList));
                        IntPtr pidlSubItem;
                        int    celtFetched;

                        while (!IOTools.IsCancelTriggered(cancel) && IEnum.Next(1, out pidlSubItem, out celtFetched) == ShellAPI.S_OK && celtFetched == 1)
                        {
                            ShellAPI.SFGAO attribs = ShellAPI.SFGAO.FOLDER | ShellAPI.SFGAO.FILESYSTEM | ShellAPI.SFGAO.STREAM;
                            sf.GetAttributesOf(1, new IntPtr[] { pidlSubItem }, ref attribs);
                            //http://www.eggheadcafe.com/aspnet_answers/platformsdkshell/Mar2006/post26165601.asp
                            bool isZip = ((attribs & ShellAPI.SFGAO.FOLDER) != 0 && (attribs & ShellAPI.SFGAO.STREAM) != 0);
                            bool isDir = ((attribs & ShellAPI.SFGAO.FOLDER) != 0);
                            if (isZip || !isDir)
                            {
                                PIDL subRelPidl = new PIDL(pidlSubItem, false);
                                //FileInfoEx fi = new FileInfoEx(sf, this, subRelPidl);
                                FileInfoEx fi = new FileInfoEx(sf, parentPIDL, subRelPidl);
                                if (IOTools.MatchFileMask(fi.Name, searchPattern))
                                {
                                    yield return(fi);
                                }
                                //0.18: Fixed DirectoryInfoEx.EnumerateFiles, SearchPattern is ignored.
                            }
                        }

                        if (searchOption == SearchOption.AllDirectories)
                        {
                            IEnumerator <DirectoryInfoEx> dirEnumerator = EnumerateDirectories("*", SearchOption.TopDirectoryOnly, cancel).GetEnumerator();

                            while (!IOTools.IsCancelTriggered(cancel) && dirEnumerator.MoveNext())
                            {
                                IEnumerator <FileInfoEx> fileEnumerator = dirEnumerator.Current.EnumerateFiles(searchPattern, searchOption, cancel).GetEnumerator();

                                while (fileEnumerator.MoveNext())
                                {
                                    //Debug.Assert(!fileEnumerator.Current.IsFolder);
                                    yield return(fileEnumerator.Current);
                                }
                            }
                        }
                    }
                }
                finally
                {
                    if (parentPIDL != null)
                    {
                        parentPIDL.Free();
                        parentPIDL = null;
                    }

                    if (IEnum != null)
                    {
                        Marshal.ReleaseComObject(IEnum);
                        Marshal.Release(ptrEnum);
                    }
                }
        }
示例#28
0
        public IEnumerable <DirectoryInfoEx> EnumerateDirectories(String searchPattern, SearchOption searchOption, CancelDelegate cancel)
        {
            IntPtr      ptrEnum    = IntPtr.Zero;
            IEnumIDList IEnum      = null;
            PIDL        parentPIDL = this.PIDL;

            using (ShellFolder2 sf = this.ShellFolder)
                try
                {
                    if (sf.EnumObjects(IntPtr.Zero, flag, out ptrEnum) == ShellAPI.S_OK)
                    {
                        IEnum = (IEnumIDList)Marshal.GetTypedObjectForIUnknown(ptrEnum, typeof(IEnumIDList));
                        IntPtr pidlSubItem;
                        int    celtFetched;

                        while (!IOTools.IsCancelTriggered(cancel) && IEnum.Next(1, out pidlSubItem, out celtFetched) == ShellAPI.S_OK && celtFetched == 1)
                        {
                            ShellAPI.SFGAO attribs = ShellAPI.SFGAO.FOLDER | ShellAPI.SFGAO.FILESYSTEM | ShellAPI.SFGAO.STREAM |
                                                     ShellAPI.SFGAO.FILESYSANCESTOR | ShellAPI.SFGAO.NONENUMERATED;
                            sf.GetAttributesOf(1, new IntPtr[] { pidlSubItem }, ref attribs);
                            bool isZip = ((attribs & ShellAPI.SFGAO.FOLDER) != 0 && (attribs & ShellAPI.SFGAO.STREAM) != 0);
                            bool isDir = ((attribs & ShellAPI.SFGAO.FOLDER) != 0);
                            //0.18 Added a check for NonEnumerated items so DirectoryInfoEx.EnumerateDirectories wont return some system directories (e.g. C:\MSOCache)
                            //bool isNonEnumerated = ((attribs & ShellAPI.SFGAO.NONENUMERATED) != 0);
                            bool isFileAncestor = ((attribs & ShellAPI.SFGAO.FILESYSANCESTOR) != 0);
                            bool includedFolder = false;

                            if (!isZip && !isFileAncestor) //0.14 : Added allowed folder list so Non-FileAncestor directory (e.g. recycle-bin) is listed.
                            {
                                string[] allowedPaths = new string[]
                                {
                                    "::{645FF040-5081-101B-9F08-00AA002F954E}"
                                };
                                string path = PIDLToPath(new PIDL(pidlSubItem, false));
                                foreach (string allowedPath in allowedPaths)
                                {
                                    if (allowedPath == path)
                                    {
                                        includedFolder = true;
                                    }
                                }
                                if (!includedFolder)
                                {
                                    if (IOTools.HasParent(this, NetworkDirectory))
                                    {
                                        includedFolder = true;
                                    }
                                }
                            }
                            if (isDir && !isZip /*&& !isNonEnumerated*/ && (isFileAncestor || includedFolder))
                            {
                                PIDL subPidl = new PIDL(pidlSubItem, false);
                                //DirectoryInfoEx di = new DirectoryInfoEx(this, subPidl);

                                //0.22: Fix illegal PIDL for Directory under Library.ms directory
                                bool            isLibraryItem = IOTools.IsLibraryItem(FullName);
                                DirectoryInfoEx di            = new DirectoryInfoEx(sf, parentPIDL, subPidl, isLibraryItem);

                                if (IOTools.MatchFileMask(di.Name, searchPattern))
                                {
                                    yield return(di);
                                }
                                if (searchOption == SearchOption.AllDirectories)
                                {
                                    IEnumerator <DirectoryInfoEx> dirEnumerator = di.EnumerateDirectories(searchPattern, searchOption, cancel).GetEnumerator();

                                    while (dirEnumerator.MoveNext())
                                    {
                                        //Debug.Assert(dirEnumerator.Current.IsFolder);
                                        yield return(dirEnumerator.Current);
                                    }
                                }
                            }
                        }
                    }
                }
                finally
                {
                    if (parentPIDL != null)
                    {
                        parentPIDL.Free();
                        parentPIDL = null;
                    }

                    if (IEnum != null)
                    {
                        Marshal.ReleaseComObject(IEnum);
                        Marshal.Release(ptrEnum);
                    }
                }
        }