/// <summary>
        /// Creates a new item enumeration object with the same contents and state as the current one.
        /// </summary>
        /// <param name="ppenum">Address of a pointer to the new enumeration object. The calling application must
        /// eventually free the new object by calling its Release member function.</param>
        public int Clone(out IEnumIDList ppenum)
        {
            //  Create a brand new enumerator, pointing at the same object
            //  and move it's index to the same position.
            ppenum = new ShellNamespaceFolderIdListEnumerator(shellNamespaceFolder, flags, currentIndex);

            //  We're done.
            return WinError.S_OK;
        }
예제 #2
0
        /// <summary>
        /// Allows a client to determine the contents of a folder by creating an item identifier enumeration object and returning its IEnumIDList interface.
        /// Return value: error code, if any
        /// </summary>
        /// <param name="hwnd">If user input is required to perform the enumeration, this window handle should be used by the enumeration object as the parent window to take user input.</param>
        /// <param name="grfFlags">Flags indicating which items to include in the  enumeration. For a list of possible values, see the SHCONTF enum.</param>
        /// <param name="ppenumIDList">Address that receives a pointer to the IEnumIDList interface of the enumeration object created by this method.</param>
        /// <returns>
        /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
        /// </returns>
        /// <exception cref="System.NotImplementedException"></exception>
        int IShellFolder.EnumObjects(IntPtr hwnd, SHCONTF grfFlags, out IEnumIDList ppenumIDList)
        {
            //  Create an object that will enumerate the contents of this shell folder (that implements
            //  IEnumIdList). This can be returned to the shell.
            ppenumIDList = new ShellNamespaceFolderIdListEnumerator(proxyFolder, grfFlags, 0);

            //  TODO we should also store the window handle for user interaction.

            //  We're done.
            return WinError.S_OK;
        }
예제 #3
0
        /// <summary>
        /// Allows a client to determine the contents of a folder by creating an item identifier enumeration object and returning its IEnumIDList interface.
        /// Return value: error code, if any
        /// </summary>
        /// <param name="hwnd">If user input is required to perform the enumeration, this window handle should be used by the enumeration object as the parent window to take user input.</param>
        /// <param name="grfFlags">Flags indicating which items to include in the  enumeration. For a list of possible values, see the SHCONTF enum.</param>
        /// <param name="ppenumIDList">Address that receives a pointer to the IEnumIDList interface of the enumeration object created by this method.</param>
        /// <returns>
        /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
        /// </returns>
        /// <exception cref="System.NotImplementedException"></exception>
        int IShellFolder.EnumObjects(IntPtr hwnd, SHCONTF grfFlags, out IEnumIDList ppenumIDList)
        {
            //  Create an object that will enumerate the contents of this shell folder (that implements
            //  IEnumIdList). This can be returned to the shell.
            ppenumIDList = new ShellNamespaceFolderIdListEnumerator(proxyFolder, grfFlags, 0);

            //  TODO we should also store the window handle for user interaction.

            //  We're done.
            return(WinError.S_OK);
        }
예제 #4
0
        private void treeView1_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            #region 判断节点是否已经展开
            if (e.Node.Nodes.Count != 1)
            {
                return;
            }
            else
            {
                if (e.Node.FirstNode.Text != "...")
                {
                    return;
                }
            }

            e.Node.Nodes.Clear();
            #endregion
            try // 因为文件夹安全设置和设备准备问题,可能导致失败。
            {
                ShellItem    sItem = (ShellItem)e.Node.Tag;
                IShellFolder root  = sItem.ShellFolder;

                //循环查找子项
                IEnumIDList Enum    = null;
                IntPtr      EnumPtr = IntPtr.Zero;
                IntPtr      pidlSub;
                int         celtFetched;

                if (root.EnumObjects(this.Handle, SHCONTF.FOLDERS | SHCONTF.INCLUDEHIDDEN, out EnumPtr) == API.S_OK)
                {
                    Enum = (IEnumIDList)Marshal.GetObjectForIUnknown(EnumPtr);
                    while (Enum.Next(1, out pidlSub, out celtFetched) == 0 && celtFetched == API.S_FALSE)
                    {
                        string       name = API.GetNameByIShell(root, pidlSub);
                        IShellFolder iSub;
                        root.BindToObject(pidlSub, IntPtr.Zero, ref Guids.IID_IShellFolder, out iSub);

                        ShellItem shellItem = new ShellItem(pidlSub, iSub, sItem);
                        int       imgIndex  = API.GetSmallIconIndex(shellItem.PIDLFull.Ptr);
                        TreeNode  nodeSub   = new TreeNode(name, imgIndex, imgIndex);

                        nodeSub.Tag = shellItem;
                        nodeSub.Nodes.Add("...");
                        e.Node.Nodes.Add(nodeSub);
                    }
                }
            }catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
예제 #5
0
        public IEnumerator <IListItemEx> GetEnumerator()
        {
            IShellFolder folder = this.GetIShellFolder();

            if (folder == null)
            {
                yield return(null);
            }
            HResult     navRes;
            IEnumIDList enumId = ShellItem.GetIEnumIDList(folder, SHCONTF.FOLDERS | SHCONTF.INCLUDEHIDDEN | SHCONTF.INCLUDESUPERHIDDEN | SHCONTF.FASTITEMS |
                                                          SHCONTF.NONFOLDERS | SHCONTF.ENABLE_ASYNC | SHCONTF.INIT_ON_FIRST_NEXT, out navRes);

            this.NavigationStatus = navRes;
            uint   count;
            IntPtr pidl;

            if (enumId == null)
            {
                yield break;
            }

            HResult result = enumId.Next(1, out pidl, out count);
            var     i      = 0;

            //var parentItem = new ShellItem(this._Item.Pidl); //this._Item;//this.IsSearchFolder ? this._Item : new ShellItem(this.ParsingName.ToShellParsingName());
            while (result == HResult.S_OK)
            {
                var fsi = new FileSystemListItem();
                try {
                    fsi.InitializeWithParent(this._Item, this.ParentHandle, pidl, i++);
                }
                catch {
                    continue;
                }
                fsi.IsParentSearchFolder = this.IsSearchFolder;
                yield return(fsi);

                Shell32.ILFree(pidl);
                result = enumId.Next(1, out pidl, out count);
            }

            if (result != HResult.S_FALSE)
            {
                //Marshal.ThrowExceptionForHR((int)result);
            }

            //parentItem.Dispose();
            yield break;
        }
예제 #6
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}");
            }
        }
예제 #7
0
        public List <Uri> GetResources(Uri uri)
        {
            var list = new List <Uri>();

            var item = GetItem(uri);

            IntPtr pidl = Shell32.SHGetIDListFromObject(item);

            try{
                var psf = Shell32.SHBindToObject <IShellFolder>(null, pidl, null);
                try{
                    IEnumIDList peidl = psf.EnumObjects(OwnerHwnd, EnumConst);

                    if (peidl == null)
                    {
                        return(list);
                    }
                    try{
                        while (true)
                        {
                            IntPtr pidl2;
                            int    num;
                            peidl.Next(1, out pidl2, out num);
                            if (num == 0)
                            {
                                break;
                            }
                            try{
                                IntPtr pidl3 = Shell32.ILCombine(pidl, pidl2);
                                list.Add(GetShellUri(pidl3, true));
                            }finally{
                                Marshal.FreeCoTaskMem(pidl2);
                            }
                        }
                    }finally{
                        Marshal.FinalReleaseComObject(peidl);
                    }
                }finally{
                    Marshal.FinalReleaseComObject(psf);
                }
            }finally{
                Marshal.FreeCoTaskMem(pidl);
            }

            return(list);
        }
예제 #8
0
        public IEnumerable <IDLWrapper> GetItems(bool selectedOnly = false, bool noAppend = false)
        {
            Guid        guid = ExplorerGUIDs.IID_IEnumIDList;
            IEnumIDList list = null;

            try {
                using (FVWrapper w = GetFolderView())
                    using (IDLWrapper path = noAppend ? null : GetShellPath(w.FolderView)) {
                        if (w == null)
                        {
                            yield break;
                        }
                        w.FolderView.Items(0x80000000 | (selectedOnly ? 1u : 2u), ref guid, out list);
                        if (list == null)
                        {
                            yield break;
                        }
                        IntPtr ptr;
                        while (list.Next(1, out ptr, null) == 0)
                        {
                            using (IDLWrapper wrapper1 = new IDLWrapper(ptr)) {
                                if (!wrapper1.Available)
                                {
                                    continue;
                                }
                                if (noAppend)
                                {
                                    yield return(wrapper1);
                                }
                                else
                                {
                                    using (IDLWrapper wrapper2 = new IDLWrapper(PInvoke.ILCombine(path.PIDL, wrapper1.PIDL))) {
                                        yield return(wrapper2);
                                    }
                                }
                            }
                        }
                    }
            }
            finally {
                if (list != null)
                {
                    Marshal.ReleaseComObject(list);
                }
            }
        }
예제 #9
0
        public IEnumerable <IDLWrapper> GetItems(bool selectedOnly = false, bool noAppend = false)
        {
            if (folderView == null)
            {
                yield break;
            }
            Guid        guid = ExplorerGUIDs.IID_IEnumIDList;
            IEnumIDList list = null;

            try {
                using (IDLWrapper path = noAppend ? null : GetShellPath()) {
                    folderView.Items(SVGIO.FLAG_VIEWORDER | (selectedOnly ? SVGIO.SELECTION : SVGIO.ALLVIEW), ref guid, out list);
                    if (list == null)
                    {
                        yield break;
                    }
                    IntPtr ptr;
                    while (list.Next(1, out ptr, null) == 0)
                    {
                        using (IDLWrapper wrapper1 = new IDLWrapper(ptr)) {
                            if (!wrapper1.Available)
                            {
                                continue;
                            }
                            if (noAppend)
                            {
                                yield return(wrapper1);
                            }
                            else
                            {
                                using (IDLWrapper wrapper2 = new IDLWrapper(PInvoke.ILCombine(path.PIDL, wrapper1.PIDL))) {
                                    yield return(wrapper2);
                                }
                            }
                        }
                    }
                }
            }
            finally {
                if (list != null)
                {
                    Marshal.ReleaseComObject(list);
                }
            }
        }
예제 #10
0
        /// <summary>
        /// 获取非文件夹的文件
        /// </summary>
        /// <param name="root">根目录</param>
        /// <param name="handle">当前窗口句柄</param>
        /// <param name="sItem">当前项</param>
        /// <returns></returns>
        public List <ShellItem> GetNonFolders(IShellFolder root, IntPtr handle, ShellItem sItem)
        {
            List <ShellItem> allFileShellItem = new List <ShellItem>();//文件的集合

            if (root.EnumObjects(handle, SHCONTF.NONFOLDERS | SHCONTF.INCLUDEHIDDEN, out EnumPtr) ==
                API.S_OK)
            {
                Enum = (IEnumIDList)Marshal.GetObjectForIUnknown(EnumPtr);
                IntPtr pidlSub;
                int    celtFetched;
                while (Enum.Next(1, out pidlSub, out celtFetched) == 0 && celtFetched == API.S_FALSE)
                {
                    var shellItem = new ShellItem(pidlSub, null, sItem);
                    allFileShellItem.Add(shellItem);
                }
            }
            return(allFileShellItem);
        }
예제 #11
0
 private void freeResources(IntPtr pidlMain, IShellFolder folder, IEnumIDList idEnum, IShellFolder item)
 {
     if (idEnum != null)
     {
         Marshal.ReleaseComObject(idEnum);
     }
     if (item != null)
     {
         Marshal.ReleaseComObject(item);
     }
     if (pidlMain != IntPtr.Zero)
     {
         allocator.Free(pidlMain);
     }
     if (folder != null)
     {
         Marshal.ReleaseComObject(folder);
     }
 }
예제 #12
0
        /// <summary>
        /// Get PIDL and parent shellfolder for given file path
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        private static PIDLShellFolder GetPIDLAndParentIshellFolderForFile(string filePath)
        {
            //get desktopPtr first
            IntPtr       desktopPtr;
            IShellFolder desktop = GetDesktopFolder(out desktopPtr);

            string       fileName = Path.GetFileName(filePath);
            IShellFolder parentShellFolder;
            string       FolderPath = Directory.GetParent(filePath).FullName;
            IntPtr       Pidl = IntPtr.Zero;
            uint         i, j = 0;

            desktop.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, FolderPath, out i, out Pidl, ref j);
            desktop.BindToObject(Pidl, IntPtr.Zero, ref Guids.IID_IShellFolder, out parentShellFolder);
            Marshal.ReleaseComObject(desktop);

            IEnumIDList fileEnum      = null;
            IEnumIDList folderEnum    = null;
            IntPtr      fileEnumPtr   = IntPtr.Zero;
            IntPtr      folderEnumPtr = IntPtr.Zero;
            IntPtr      pidlSub;
            int         celtFetched;

            if (parentShellFolder.EnumObjects(IntPtr.Zero, SHCONTF.NONFOLDERS | SHCONTF.INCLUDEHIDDEN, out folderEnumPtr) == ShellAPI.S_OK)
            {
                folderEnum = (IEnumIDList)Marshal.GetObjectForIUnknown(folderEnumPtr);
                while (folderEnum.Next(1, out pidlSub, out celtFetched) == 0 && celtFetched == ShellAPI.S_FALSE)
                {
                    string name = ShellAPI.GetNameByPIDL(pidlSub);
                    if (name == fileName)
                    {
                        PIDLShellFolder ps = new PIDLShellFolder {
                            PIDL = pidlSub, ShellFolder = parentShellFolder
                        };
                        Marshal.ReleaseComObject(parentShellFolder);
                        return(ps);
                    }
                }
            }

            Marshal.ReleaseComObject(parentShellFolder);
            return(null);
        }
예제 #13
0
        /// <summary>
        /// Enumerates all children of this item. If this item is not a folder/container, this method will return an empty enumeration.
        /// </summary>
        /// <param name="filter">A filter for the types of children to enumerate.</param>
        /// <param name="parentWindow">The parent window.</param>
        /// <returns>An enumerated list of children matching the filter.</returns>
        public IEnumerable <ShellItem> EnumerateChildren(FolderItemFilter filter /*= FolderItemFilter.Folders | FolderItemFilter.IncludeHidden | FolderItemFilter.NonFolders | FolderItemFilter.IncludeSuperHidden */, System.Windows.Forms.IWin32Window parentWindow = null)
        {
            IEnumIDList eo = null;

            try
            {
                eo = iShellFolder.EnumObjects(IWin2Ptr(parentWindow, false), (SHCONTF)filter);
            }
            catch (Exception e) { Debug.WriteLine($"Unable to enum children in folder: {e.Message}"); }
            foreach (var p in eo.Enumerate(20))
            {
                ShellItem i = null;
                try { i = this[p]; } catch (Exception e) { Debug.WriteLine($"Unable to open folder child: {e.Message}"); }
                if (i != null)
                {
                    yield return(i);
                }
            }
            Marshal.ReleaseComObject(eo);
        }
예제 #14
0
            public override List <ResourceInfo> GetResources()
            {
                var list = new List <ResourceInfo>();

                var psf = Shell32.SHBindToObject <IShellFolder>(null, pidl, null);

                try{
                    IEnumIDList peidl = psf.EnumObjects(fs.OwnerHwnd, EnumConst);

                    if (peidl == null)
                    {
                        return(list);
                    }
                    try{
                        while (true)
                        {
                            IntPtr pidl2;
                            int    num;
                            peidl.Next(1, out pidl2, out num);
                            if (num == 0)
                            {
                                break;
                            }
                            try{
                                IntPtr pidl3 = Shell32.ILCombine(pidl, pidl2);
                                list.Add(new ShellFileHandle(pidl3, fs, true));
                            }finally{
                                Marshal.FreeCoTaskMem(pidl2);
                            }
                        }
                    }finally{
                        Marshal.FinalReleaseComObject(peidl);
                    }
                }finally{
                    Marshal.FinalReleaseComObject(psf);
                }

                return(list);
            }
예제 #15
0
        public FShellFile[] ListFile()
        {
            IntPtr ptr = IntPtr.Zero;

            if (_face.EnumObjects(_handle, EShcontf.NonFolders | EShcontf.IncludeHidden, out ptr) == RWinShell.S_OK)
            {
                IntPtr pidlSub;
                int    celtFetched;
                FObjects <FShellFile> files = new FObjects <FShellFile>();
                IEnumIDList           list  = (IEnumIDList)Marshal.GetObjectForIUnknown(ptr);
                while (list.Next(1, out pidlSub, out celtFetched) == RWinShell.S_OK && celtFetched == RWinShell.S_FALSE)
                {
                    FShellFile file = new FShellFile();
                    file.Parent = this;
                    file.SetHandle(pidlSub);
                    file.RefreshInfo();
                    files.Push(file);
                }
                return(files.ToArray());
            }
            return(null);
        }
예제 #16
0
        /// <summary>
        /// Enumerates all children of this item. If this item is not a folder/container, this method will return an empty enumeration.
        /// </summary>
        /// <param name="filter">A filter for the types of children to enumerate.</param>
        /// <param name="parentWindow">The parent window.</param>
        /// <returns>An enumerated list of children matching the filter.</returns>
        public IEnumerable <ShellItem> EnumerateChildren(FolderItemFilter filter /*= FolderItemFilter.Folders | FolderItemFilter.IncludeHidden | FolderItemFilter.NonFolders | FolderItemFilter.IncludeSuperHidden */, System.Windows.Forms.IWin32Window parentWindow = null)
        {
            IEnumIDList eo = null;

            try
            {
                eo = iShellFolder.EnumObjects(IWin2Ptr(parentWindow, false), (SHCONTF)filter);
            }
            catch (Exception e) { Debug.WriteLine($"Unable to enum children in folder: {e.Message}"); }
            if (eo != null)
            {
                foreach (var p in new Collections.IEnumFromNext <IntPtr>((out IntPtr p) => eo.Next(1, out p, out var f).Succeeded&& f == 1, () => { try { eo.Reset(); } catch { } }))
                {
                    ShellItem i = null;
                    try { i = this[new PIDL(p)]; } catch (Exception e) { Debug.WriteLine($"Unable to open folder child: {e.Message}"); }
                    if (i != null)
                    {
                        yield return(i);
                    }
                }
                Marshal.ReleaseComObject(eo);
            }
        }
예제 #17
0
        public static List <ShellItem> GetItems(Guid FolderID) //Получает список элементов каталога по GUID
        {
            IntPtr           p       = IntPtr.Zero;
            IShellFolder     pFolder = null;
            IEnumIDList      pEnum   = null;
            IntPtr           pItem   = IntPtr.Zero;
            IntPtr           lpStr   = IntPtr.Zero;
            STRRET           strret;
            Guid             guid  = typeof(IShellFolder).GUID;
            List <ShellItem> items = new List <ShellItem>();
            ShellItem        si;

            try
            {
                int hr = NativeMethods.SHGetKnownFolderIDList(ref FolderID, 0, IntPtr.Zero, out p);
                if (hr != 0)
                {
                    throw Marshal.GetExceptionForHR(hr);
                }

                hr = NativeMethods.SHBindToObject(null, p, null, ref guid, out pFolder);
                if (hr != 0)
                {
                    throw Marshal.GetExceptionForHR(hr);
                }

                pFolder.EnumObjects(IntPtr.Zero, NativeMethods.SHCONTF_FOLDERS | NativeMethods.SHCONTF_NONFOLDERS, out pEnum);

                while (true)
                {
                    pItem = IntPtr.Zero;
                    uint res = pEnum.Next(1, out pItem, IntPtr.Zero);
                    if (res != 0)
                    {
                        break;
                    }
                    si = new ShellItem();

                    //display name
                    lpStr  = IntPtr.Zero;
                    strret = new STRRET();
                    pFolder.GetDisplayNameOf(pItem, NativeMethods.SHGDN_NORMAL, out strret);
                    hr = NativeMethods.StrRetToStr(ref strret, pItem, out lpStr);
                    if (hr != 0)
                    {
                        throw Marshal.GetExceptionForHR(hr);
                    }
                    string s = Marshal.PtrToStringUni(lpStr);
                    si.DisplayName = s;
                    NativeMethods.CoTaskMemFree(lpStr);

                    //path
                    lpStr  = IntPtr.Zero;
                    strret = new STRRET();
                    pFolder.GetDisplayNameOf(pItem, NativeMethods.SHGDN_FORPARSING, out strret);
                    hr = NativeMethods.StrRetToStr(ref strret, pItem, out lpStr);
                    if (hr != 0)
                    {
                        throw Marshal.GetExceptionForHR(hr);
                    }
                    s = Marshal.PtrToStringUni(lpStr);
                    try { si.Path = new Uri(s); }
                    catch (UriFormatException) { si.Path = new Uri("file://localhost/" + s); }
                    NativeMethods.CoTaskMemFree(lpStr);

                    //icon
                    try
                    {
                        Guid         iid_IIExtractIcon = typeof(IExtractIcon).GUID;
                        IExtractIcon pExtract;
                        pFolder.GetUIObjectOf(IntPtr.Zero, 1, new IntPtr[] { pItem }, ref iid_IIExtractIcon, 0, out pExtract);

                        StringBuilder sbIcon = new StringBuilder(260);
                        int           index  = 0;
                        uint          flags;
                        hr = pExtract.GetIconLocation(NativeMethods.GIL_FORSHELL, sbIcon, 260, out index, out flags);
                        if (hr == 0)
                        {
                            IntPtr hIconSmall = IntPtr.Zero, hIconLarge = IntPtr.Zero;
                            hr = pExtract.Extract(sbIcon.ToString(), (uint)index, out hIconLarge, out hIconSmall, 0x00140014);
                            if (hr == 0 && hIconSmall != IntPtr.Zero)
                            {
                                var icon   = System.Drawing.Icon.FromHandle(hIconSmall);
                                var bitmap = icon.ToBitmap();

                                using (bitmap)
                                {
                                    MemoryStream ms = new MemoryStream();
                                    bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
                                    si.Image = ms.ToArray();
                                }

                                NativeMethods.DestroyIcon(hIconSmall);
                                NativeMethods.DestroyIcon(hIconLarge);
                            }
                            else
                            {
                                si.Image = new byte[0];
                            }
                        }
                        else
                        {
                            si.Image = new byte[0];
                        }
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Debug.WriteLine(ex.ToString());
                        si.Image = new byte[0];
                    }
                    items.Add(si);
                    NativeMethods.CoTaskMemFree(pItem);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), ex.GetType().ToString());
            }
            finally
            {
                if (p != IntPtr.Zero)
                {
                    NativeMethods.CoTaskMemFree(p);
                }
                if (pFolder != null)
                {
                    Marshal.ReleaseComObject(pFolder);
                }
                if (pEnum != null)
                {
                    Marshal.ReleaseComObject(pEnum);
                }
            }
            return(items);
        }
예제 #18
0
        public Bitmap GetThumbnail(string fileName)
        {
            if (!File.Exists(fileName) && !Directory.Exists(fileName))
            {
                throw new FileNotFoundException(string.Format("The file '{0}' does not exist", fileName), fileName);
            }

            if (ThumbNail != null)
            {
                ThumbNail.Dispose();
                ThumbNail = null;
            }

            var folder = getDesktopFolder;

            if (folder == null)
            {
                return(ThumbNail);
            }

            var pidlMain = IntPtr.Zero;

            try
            {
                var cParsed   = 0;
                var pdwAttrib = 0;
                var filePath  = Path.GetDirectoryName(fileName);
                folder.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, filePath, ref cParsed, ref pidlMain, ref pdwAttrib);
            }
            catch (Exception)
            {
                freeResources(pidlMain, folder, null, null);
                throw;
            }

            if (pidlMain == IntPtr.Zero)
            {
                freeResources(pidlMain, folder, null, null);
                return(null);
            }


            var          iidShellFolder = new Guid("000214E6-0000-0000-C000-000000000046");
            IShellFolder item           = null;

            try
            {
                folder.BindToObject(pidlMain, IntPtr.Zero, ref iidShellFolder, ref item);
            }
            catch (Exception)
            {
                freeResources(pidlMain, folder, null, item);
                throw;
            }

            if (item == null)
            {
                freeResources(pidlMain, folder, null, null);
                return(null);
            }

            IEnumIDList idEnum = null;

            try
            {
                item.EnumObjects(IntPtr.Zero, (Eshcontf.ShcontfFolders | Eshcontf.ShcontfNonfolders), ref idEnum);
            }
            catch (Exception)
            {
                freeResources(pidlMain, folder, idEnum, item);
                throw;
            }

            if (idEnum == null)
            {
                freeResources(pidlMain, folder, null, item);
                return(null);
            }

            var pidl     = IntPtr.Zero;
            var fetched  = 0;
            var complete = false;

            while (!complete)
            {
                var hRes = idEnum.Next(1, ref pidl, ref fetched);
                if (hRes != 0)
                {
                    pidl     = IntPtr.Zero;
                    complete = true;
                }
                else
                {
                    if (getThumbNail(fileName, pidl, item))
                    {
                        complete = true;
                    }
                }

                if (pidl != IntPtr.Zero)
                {
                    allocator.Free(pidl);
                }
            }

            freeResources(pidlMain, folder, idEnum, item);
            return(ThumbNail);
        }
예제 #19
0
		void IEnumIDList.Clone( ref IEnumIDList ppenum)
		{
			ppenum = new MSDNMagazine.Shell.HelperItems.EnumIDList(this);
		}
예제 #20
0
 void IEnumIDList.Clone(ref IEnumIDList ppenum)
 {
     ppenum = new MSDNMagazine.Shell.HelperItems.EnumIDList(this);
 }
예제 #21
0
 int IShellFolder2.EnumObjects(IntPtr hwnd, SHCONTF grfFlags, out IEnumIDList ppenumIDList)
 {
     return(((IShellFolder)this).EnumObjects(hwnd, grfFlags, out ppenumIDList));
 }
 /// <summary>
 /// Allows a client to determine the contents of a folder by creating an item identifier enumeration object and returning its IEnumIDList interface.
 /// Return value: error code, if any
 /// </summary>
 /// <param name="hwnd">If user input is required to perform the enumeration, this window handle should be used by the enumeration object as the parent window to take user input.</param>
 /// <param name="grfFlags">Flags indicating which items to include in the  enumeration. For a list of possible values, see the SHCONTF enum.</param>
 /// <param name="ppenumIDList">Address that receives a pointer to the IEnumIDList interface of the enumeration object created by this method.</param>
 /// <returns>
 /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
 /// </returns>
 /// <exception cref="System.NotImplementedException"></exception>
 int IShellFolder.EnumObjects(IntPtr hwnd, SHCONTF grfFlags, out IEnumIDList ppenumIDList)
 {
     //  Use the ShellFolderImpl to handle the details.
     return ((IShellFolder)shellFolderImpl).EnumObjects(hwnd, grfFlags, out ppenumIDList);
 }
예제 #23
0
        public Bitmap GetThumbnail(string fileName)
        {
            if (!File.Exists(fileName) && !Directory.Exists(fileName))
            {
                throw new FileNotFoundException(string.Format("The file '{0}' does not exist", fileName), fileName);
            }

            if (this.thumbNail != null)
            {
                this.thumbNail.Dispose();
                this.thumbNail = null;
            }

            IShellFolder folder = null;

            try
            {
                folder = this.DesktopFolder;
            }
            catch (Exception ex)
            {
                throw ex;
            }

            if (folder != null)
            {
                IntPtr pidlMain = IntPtr.Zero;

                try
                {
                    int    parsed    = 0;
                    int    pdwAttrib = 0;
                    string filePath  = Path.GetDirectoryName(fileName);

                    folder.ParseDisplayName(IntPtr.Zero, IntPtr.Zero, filePath, ref parsed, ref pidlMain, ref pdwAttrib);
                }
                catch (Exception ex)
                {
                    Marshal.ReleaseComObject(folder);

                    throw ex;
                }

                if (pidlMain != IntPtr.Zero)
                {
                    Guid iidShellFolder = new Guid("000214E6-0000-0000-C000-000000000046");

                    IShellFolder item = null;

                    try
                    {
                        folder.BindToObject(pidlMain, IntPtr.Zero, ref iidShellFolder, ref item);
                    }
                    catch (Exception ex)
                    {
                        Marshal.ReleaseComObject(folder);

                        this.Allocator.Free(pidlMain);

                        throw ex;
                    }

                    if (item != null)
                    {
                        IEnumIDList idEnum = null;

                        try
                        {
                            item.EnumObjects(IntPtr.Zero, (ESHCONTF.SHCONTF_FOLDERS | ESHCONTF.SHCONTF_NONFOLDERS), ref idEnum);
                        }
                        catch (Exception ex)
                        {
                            Marshal.ReleaseComObject(folder);

                            this.Allocator.Free(pidlMain);

                            throw ex;
                        }

                        if (idEnum != null)
                        {
                            int    res      = 0;
                            IntPtr pidl     = IntPtr.Zero;
                            int    fetched  = 0;
                            bool   complete = false;

                            while (!complete)
                            {
                                res = idEnum.Next(1, ref pidl, ref fetched);

                                if (res != 0)
                                {
                                    pidl     = IntPtr.Zero;
                                    complete = true;
                                }
                                else
                                {
                                    if (this.GetThumbnailHelper(fileName, pidl, item))
                                    {
                                        complete = true;
                                    }
                                }

                                if (pidl != IntPtr.Zero)
                                {
                                    this.Allocator.Free(pidl);
                                }
                            }

                            Marshal.ReleaseComObject(idEnum);
                        }

                        Marshal.ReleaseComObject(item);
                    }

                    this.Allocator.Free(pidlMain);
                }

                Marshal.ReleaseComObject(folder);
            }

            return(this.ThumbNail);
        }
예제 #24
0
 /// <summary>
 /// Allows a client to determine the contents of a folder by creating an item identifier enumeration object and returning its IEnumIDList interface.
 /// Return value: error code, if any
 /// </summary>
 /// <param name="hwnd">If user input is required to perform the enumeration, this window handle should be used by the enumeration object as the parent window to take user input.</param>
 /// <param name="grfFlags">Flags indicating which items to include in the  enumeration. For a list of possible values, see the SHCONTF enum.</param>
 /// <param name="ppenumIDList">Address that receives a pointer to the IEnumIDList interface of the enumeration object created by this method.</param>
 /// <returns>
 /// If this method succeeds, it returns S_OK. Otherwise, it returns an HRESULT error code.
 /// </returns>
 /// <exception cref="System.NotImplementedException"></exception>
 int IShellFolder.EnumObjects(IntPtr hwnd, SHCONTF grfFlags, out IEnumIDList ppenumIDList)
 {
     //  Use the ShellFolderImpl to handle the details.
     return(((IShellFolder)shellFolderImpl).EnumObjects(hwnd, grfFlags, out ppenumIDList));
 }
        int IShellFolder2.EnumObjects(IntPtr hwnd, SHCONTF grfFlags, out IEnumIDList ppenumIDList)
        {
            return ((IShellFolder2)shellFolderImpl).EnumObjects(hwnd, grfFlags, out ppenumIDList);

        }
예제 #26
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);
                    }
                }
        }
예제 #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 static NativeEnumIDList ToNative(this IEnumIDList @this)
 {
     return(@this != null ? new NativeEnumIDList(@this) : null);
 }
예제 #29
0
        public System.Drawing.Bitmap GetThumbnail(string file, int width, int height)
        {
            if ((!File.Exists(file)) && (!Directory.Exists(file)))
            {
                throw new FileNotFoundException(
                          String.Format("The file '{0}' does not exist", file),
                          file);
            }

            if (thumbNail != null)
            {
                thumbNail.Dispose();
                thumbNail = null;
            }

            IShellFolder folder = null;

            try
            {
                folder = GetDesktopFolder;
            }
            catch (Exception ex)
            {
                throw ex;
            }

            if (folder != null)
            {
                IntPtr pidlMain = IntPtr.Zero;
                try
                {
                    int    cParsed   = 0;
                    int    pdwAttrib = 0;
                    string filePath  = Path.GetDirectoryName(file);
                    pidlMain = IntPtr.Zero;
                    folder.ParseDisplayName(
                        IntPtr.Zero,
                        IntPtr.Zero,
                        filePath,
                        out cParsed,
                        out pidlMain,
                        out pdwAttrib);
                }
                catch (Exception ex)
                {
                    Marshal.ReleaseComObject(folder);
                    throw ex;
                }

                if (pidlMain != IntPtr.Zero)
                {
                    // IShellFolder:
                    Guid         iidShellFolder = new Guid("000214E6-0000-0000-C000-000000000046");
                    IShellFolder item           = null;

                    try
                    {
                        folder.BindToObject(pidlMain, IntPtr.Zero, ref
                                            iidShellFolder, ref item);
                    }
                    catch (Exception ex)
                    {
                        Marshal.ReleaseComObject(folder);
                        UnmanagedMethods.CoTaskMemFree(pidlMain);
                        throw ex;
                    }

                    if (item != null)
                    {
                        IEnumIDList idEnum = null;
                        try
                        {
                            item.EnumObjects(
                                IntPtr.Zero,
                                (ESHCONTF.SHCONTF_FOLDERS |
                                 ESHCONTF.SHCONTF_NONFOLDERS),
                                ref idEnum);
                        }
                        catch (Exception ex)
                        {
                            Marshal.ReleaseComObject(folder);
                            UnmanagedMethods.CoTaskMemFree(pidlMain);
                            throw ex;
                        }

                        if (idEnum != null)
                        {
                            int    hRes     = 0;
                            IntPtr pidl     = IntPtr.Zero;
                            int    fetched  = 0;
                            bool   complete = false;
                            while (!complete)
                            {
                                hRes = idEnum.Next(1, ref pidl, out fetched);
                                if (hRes != 0)
                                {
                                    pidl     = IntPtr.Zero;
                                    complete = true;
                                }
                                else
                                {
                                    if (GetThumbnail(file, pidl, item, width, height))
                                    {
                                        complete = true;
                                    }
                                }
                                if (pidl != IntPtr.Zero)
                                {
                                    UnmanagedMethods.CoTaskMemFree(pidl);
                                }
                            }

                            Marshal.ReleaseComObject(idEnum);
                        }


                        Marshal.ReleaseComObject(item);
                    }

                    UnmanagedMethods.CoTaskMemFree(pidlMain);
                }

                Marshal.ReleaseComObject(folder);
            }
            return(thumbNail);
        }
예제 #30
0
 private void freeResources(IntPtr pidlMain, IShellFolder folder, IEnumIDList idEnum, IShellFolder item)
 {
     if (idEnum != null) Marshal.ReleaseComObject(idEnum);
     if (item != null) Marshal.ReleaseComObject(item);
     if (pidlMain != IntPtr.Zero) allocator.Free(pidlMain);
     if (folder != null) Marshal.ReleaseComObject(folder);
 }
예제 #31
0
 void IEnumIDList.Clone(out IEnumIDList ppenum)
 {
     throw new NotSupportedException();
 }
예제 #32
0
        public void CanEnumerateDesktopFolders()
        {
            // Defines the type of items that we want to retieve below the desktop root item
            const SHCONTF flags = SHCONTF.NONFOLDERS | SHCONTF.FOLDERS | SHCONTF.INCLUDEHIDDEN;

            //  Get the desktop root folder.
            IntPtr        ptrDesktopFolder = default(IntPtr);
            IntPtr        enumerator       = default(IntPtr);
            IShellFolder2 iDesktopFolder   = null;

            // Enumerate over children of given shell folder item using this interface
            // https://msdn.microsoft.com/en-us/library/windows/desktop/bb761983(v=vs.85).aspx
            IEnumIDList enumIDs = null;

            try
            {
                HRESULT hr = NativeMethods.SHGetDesktopFolder(out ptrDesktopFolder);

                Assert.IsTrue(hr == HRESULT.S_OK);

                if (ptrDesktopFolder != IntPtr.Zero)
                {
                    iDesktopFolder = (IShellFolder2)Marshal.GetTypedObjectForIUnknown(ptrDesktopFolder, typeof(IShellFolder2));
                }

                Assert.IsTrue(iDesktopFolder != null);

                //  Create an enumerator and enumerate over each item.
                hr = iDesktopFolder.EnumObjects(IntPtr.Zero, flags, out enumerator);

                Assert.IsTrue(hr == HRESULT.S_OK);

                // Convert enum IntPtr to interface
                enumIDs = (IEnumIDList)Marshal.GetTypedObjectForIUnknown(enumerator, typeof(IEnumIDList));

                Assert.IsTrue(enumIDs != null);

                uint   fetched, count = 0;
                IntPtr apidl = default(IntPtr);

                // Get one item below desktop root at a time and process by getting its display name
                for (; enumIDs.Next(1, out apidl, out fetched) == HRESULT.S_OK; count++)
                {
                    if (fetched <= 0)  // End this loop if no more items are available
                    {
                        break;
                    }

                    IntPtr ptrStr = default(IntPtr); // get strings for this item
                    try
                    {
                        string displayName = null, parseName = null;

                        ptrStr = Marshal.AllocCoTaskMem(NativeMethods.MAX_PATH * 2 + 4);
                        Marshal.WriteInt32(ptrStr, 0, 0);
                        StringBuilder buf = new StringBuilder(NativeMethods.MAX_PATH);

                        // The apidl ITEMIDLIST structures returned in the array are relative to
                        // the IShellFolder being enumerated.
                        if (iDesktopFolder.GetDisplayNameOf(apidl, SHGDNF.SHGDN_NORMAL, ptrStr) == HRESULT.S_OK)
                        {
                            NativeMethods.StrRetToBuf(ptrStr, ptrDesktopFolder, buf, NativeMethods.MAX_PATH);
                            displayName = buf.ToString();
                        }

                        if (iDesktopFolder.GetDisplayNameOf(apidl, SHGDNF.SHGDN_FORPARSING, ptrStr) == HRESULT.S_OK)
                        {
                            NativeMethods.StrRetToBuf(ptrStr, ptrDesktopFolder, buf, NativeMethods.MAX_PATH);
                            parseName = buf.ToString();
                        }

                        Assert.IsFalse(string.IsNullOrEmpty(displayName));
                        Assert.IsFalse(string.IsNullOrEmpty(parseName));
                    }
                    finally
                    {
                        ptrStr = PidlManager.FreeCoTaskMem(ptrStr);
                        apidl  = PidlManager.FreeCoTaskMem(apidl);
                    }
                }

                // There should be more than one item below the desktop root item
                // 'My PC', 'Recycle Bin', and 'Network' are already three
                Assert.IsTrue(count > 2);
            }
            finally
            {
                if (enumerator != default(IntPtr))
                {
                    Marshal.Release(enumerator);
                }

                if (iDesktopFolder != null)
                {
                    Marshal.ReleaseComObject(iDesktopFolder);
                }

                if (ptrDesktopFolder != default(IntPtr))
                {
                    Marshal.Release(ptrDesktopFolder);
                }
            }
        }