Exemplo n.º 1
0
 internal FileInfoEx(DirectoryInfoEx parentDir, PIDL relPIDL)
 {
     Parent = parentDir;
     //0.15: Fixed ShellFolder not freed.
     using (ShellFolder2 parentShellFolder = parentDir.ShellFolder)
         init(parentShellFolder, parentDir.PIDLRel, relPIDL);
 }
Exemplo n.º 2
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);
                }
            }
        }
Exemplo n.º 3
0
        private ShellFolder2 getIShellFolder()
        {
            if (this.FullName.Equals(IOTools.IID_Desktop))
            {
                return(getDesktopShellFolder());
            }
            else
            {
                ShellFolder2 retVal = getIShellFolderFromParent();
                if (retVal != null)
                {
                    return(retVal);
                }

                return(this.RequestPIDL((pidl, relPIDL) =>
                {
                    using (ShellFolder2 parentShellFolder = getParentIShellFolder(pidl, 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);
                    }
                }));
            }
        }
Exemplo n.º 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.
        }
Exemplo n.º 5
0
        /// <summary>
        /// Refresh the file / directory info. Does not refresh directory contents
        /// because it refresh every time GetFiles/Directories/FileSystemInfos is called.
        /// </summary>
        public void Refresh(RefreshModeEnum mode = RefreshModeEnum.AllProps)
        {
            RefreshMode |= mode; //0.23 : Delay loading some properties.

            PIDL relPIDL = null;

            if (!Exists)
            {
                refresh(null, null, null, mode);
            }
            else
            {
                try
                {
                    //0.16: Fixed ShellFolder not freed
                    this.RequestPIDL(pidlLookup =>
                    {
                        using (ShellFolder2 sf = getParentIShellFolder(pidlLookup, out relPIDL))
                            refresh(sf, relPIDL, pidlLookup, mode);
                    });
                }
                catch (NullReferenceException)
                {
                    refresh(null, null, null, mode);
                }
            }
Exemplo n.º 6
0
 internal FileInfoEx(DirectoryInfoEx parentDir, PIDL relPIDL)
 {
     Parent = parentDir;
     //0.15: Fixed ShellFolder not freed.
     using (ShellFolder2 parentShellFolder = parentDir.ShellFolder)
         parentDir.RequestRelativePIDL(parentRelPidl =>
                                       init(parentShellFolder, parentRelPidl, relPIDL));
 }
Exemplo n.º 7
0
 internal static string PIDLToPath(PIDL pidlFull)
 {
     if (DirectoryInfoEx.DesktopDirectory.RequestPIDL(desktopPIDL => pidlFull.Equals(desktopPIDL)))
     {
         return("::{00021400-0000-0000-C000-000000000046}");
     }
     using (ShellFolder2 _desktopShellFolder = getDesktopShellFolder())
         return(loadName(_desktopShellFolder, pidlFull, ShellAPI.SHGNO.FORPARSING));
 }
Exemplo n.º 8
0
 internal DirectoryInfoEx(DirectoryInfoEx parentDir, PIDL relPIDL)
 {
     Parent = parentDir;
     parentDir.RequestPIDL(parentPIDL =>
     {
         //0.15: Fixed ShellFolder not freed.
         using (ShellFolder2 parentShellFolder = parentDir.ShellFolder)
             init(parentShellFolder, parentPIDL, relPIDL);
     });
 }
Exemplo n.º 9
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;
            }

            IntPtr storePtr = IntPtr.Zero;

            //0.15 : Fixed PIDL not freed correctly.
            try
            {
                return(dir.RequestRelativePIDL(dirPIDLRel =>
                {
                    int hr;
                    if (dirPIDLRel.Size == 0)
                    {
                        IntPtr pidlLast = IntPtr.Zero;
                        hr = ShellAPI.SHBindToParent(dirPIDLRel.Ptr, ShellAPI.IID_IStorage,
                                                     out storePtr, 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 storePtr);
                            }
                            else
                            {
                                storePtr = IntPtr.Zero;
                                return false;
                            }
                    }

                    if ((hr != ShellAPI.S_OK))
                    {
                        storePtr = IntPtr.Zero;
                        Marshal.ThrowExceptionForHR(hr);
                        return false;
                    }

                    return true;
                }));
            }
            finally
            {
                storagePtr = storePtr;
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Convert a Parsable path to PIDL
        /// </summary>
        private static PIDL PathtoPIDL(string path)
        {
            IntPtr pidlPtr;
            uint   pchEaten = 0;

            ShellAPI.SFGAO pdwAttributes = 0;
            using (ShellFolder2 _desktopShellFolder = getDesktopShellFolder())
                _desktopShellFolder.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, path, ref pchEaten, out pidlPtr, ref pdwAttributes);
            PIDL pidl = new PIDL(pidlPtr, false);

            return(pidl);
        }
Exemplo n.º 11
0
        internal static ShellFolder2 getDesktopShellFolder()
        {
            IntPtr ptrShellFolder;
            int    hr = ShellAPI.SHGetDesktopFolder(out ptrShellFolder);

            if (hr == ShellAPI.S_OK && ptrShellFolder != IntPtr.Zero)
            {
                ShellFolder2 sf = new ShellFolder2(ptrShellFolder);
                //0.13: Fixed? Desktop ShellFolder not released. (may be a cause of AccessViolationException.)
                //GC.SuppressFinalize(sf);
                return(sf);
            }
            Marshal.ThrowExceptionForHR(hr);

            return(null); //mute error.
        }
Exemplo n.º 12
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; }
        }
Exemplo n.º 13
0
        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));
        }
Exemplo n.º 14
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;
                }
            }
        }
Exemplo n.º 15
0
 private ShellFolder2 getIShellFolderFromParent()
 {
     if (_parent != null)
     {
         using (ShellFolder2 parentShellFolder = _parent.ShellFolder)
         {
             IntPtr ptrShellFolder;
             PIDL   relPIDL = this.PIDLRel;
             int    hr      = parentShellFolder.BindToObject(relPIDL.Ptr, IntPtr.Zero, ref ShellAPI.IID_IShellFolder2,
                                                             out ptrShellFolder);
             if (ptrShellFolder != IntPtr.Zero && hr == ShellAPI.S_OK)
             {
                 return(new ShellFolder2(ptrShellFolder));
             }
         }
     }
     return(null);
 }
Exemplo n.º 16
0
        internal static PIDL PathToPIDL(string path)
        {
            path = Helper.RemoveSlash(path);
            IntPtr pidlPtr;
            uint   pchEaten = 0;

            ShellAPI.SFGAO pdwAttributes = 0;

            using (ShellFolder2 _desktopShellFolder = getDesktopShellFolder())
            {
                int hr = _desktopShellFolder.ParseDisplayName(
                    IntPtr.Zero, IntPtr.Zero, path, ref pchEaten, out pidlPtr, ref pdwAttributes);

                if (pidlPtr == IntPtr.Zero || hr != ShellAPI.S_OK)
                { /*Marshal.ThrowExceptionForHR(hr);*/
                    return(null);
                }
                //Commented because this is part of init and it's too time consuming.
            }
            return(new PIDL(pidlPtr, false));
        }
Exemplo n.º 17
0
        /// <summary>
        /// Refresh the file / directory info. Does not refresh directory contents
        /// because it refresh every time GetFiles/Directories/FileSystemInfos is called.
        /// </summary>
        public new void Refresh()
        {
            PIDL relPIDL = null;

            if (!Exists)
            {
                refresh(null, null, null);
            }
            else
            {
                try
                {
                    //0.16: Fixed ShellFolder not freed
                    using (ShellFolder2 sf = getParentIShellFolder(PIDL, out relPIDL))
                        refresh(sf, relPIDL, PIDL);
                }
                catch (NullReferenceException)
                {
                    refresh(null, null, null);
                }
            }
Exemplo n.º 18
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);
         }
     }
 }
Exemplo n.º 19
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);
                    }
                }
        }
Exemplo n.º 20
0
 internal static string PtrToPath(IntPtr ptr)
 {
     using (ShellFolder2 _desktopShellFolder = getDesktopShellFolder())
         return(loadName(_desktopShellFolder, ptr, ShellAPI.SHGNO.FORPARSING));
 }
Exemplo n.º 21
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);
                    }
                }
        }