WPF 获取文件夹的缩略图

WPF Get Thumbnail of folder

我想获取文件夹的缩略图,但我没有找到任何使用 WPF 的方法。对于 UWP,有一个函数 StorageFolder.GetThumbnailAsync()。但是在 WPF 我没有找到任何解决方案。

我能够通过 pinvoke 以一种不太干净的方式完成它,但它正在工作,因为它应该看到代码(使用 GetIcon 方法):

 public static class UITools
    {
        private const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;
        private const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010;

        /// <summary>
        /// Converts a <see cref="System.Drawing.Bitmap"/> into a WPF <see cref="BitmapSource"/>.
        /// </summary>
        /// <remarks>Uses GDI to do the conversion. Hence the call to the marshalled DeleteObject.
        /// </remarks>
        /// <param name="source">The source bitmap.</param>
        /// <returns>A BitmapSource</returns>
        public static BitmapSource ToBitmapSource(this System.Drawing.Bitmap source)
        {
            BitmapSource bitSrc = null;

            var hBitmap = source.GetHbitmap();

            try
            {
                bitSrc = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                    hBitmap,
                    IntPtr.Zero,
                    Int32Rect.Empty,
                    BitmapSizeOptions.FromEmptyOptions());
            }
            catch (Win32Exception)
            {
                bitSrc = null;
            }
            finally
            {
                DeleteObject(hBitmap);
            }

            return bitSrc;
        }

        public static BitmapSource GetIcon(string path,bool isDirectory)
        {
            IntPtr hIcon = GetJumboIcon(GetIconIndex(path,isDirectory));
            BitmapSource icon = null;

            using (Icon ico = (Icon)System.Drawing.Icon.FromHandle(hIcon).Clone())
            {

                icon = ico.ToBitmap().ToBitmapSource();
            }

            DestroyIcon(hIcon);

            return icon;
        }

        internal static int GetIconIndex(string pszFile,bool isDirectory)
        {
            uint attributes = FILE_ATTRIBUTE_NORMAL;
            if (isDirectory)
                attributes |= FILE_ATTRIBUTE_DIRECTORY;

            SHFILEINFO sfi = new SHFILEINFO();
            NativeMethods.SHGetFileInfo(pszFile
                , attributes //0
                , ref sfi
                , (uint)System.Runtime.InteropServices.Marshal.SizeOf(sfi)
                , (uint)(SHGFI.SysIconIndex | SHGFI.LargeIcon | SHGFI.UseFileAttributes));
            return sfi.iIcon;
        }

        // 256*256
        internal static IntPtr GetJumboIcon(int iImage)
        {
            IImageList spiml = null;
            Guid guil = new Guid(IID_IImageList); //or IID_IImageList2

            SHGetImageList(SHIL_EXTRALARGE, ref guil, ref spiml);
            IntPtr hIcon = IntPtr.Zero;
            spiml.GetIcon(iImage, ILD_TRANSPARENT | ILD_IMAGE, ref hIcon); //

            return hIcon;
        }

    }

如您所见,这适用于文件和文件夹。 你可以用我刚才制作的一个小工具看到它的实际效果: GitHub

使用 Windows API Code Pack mentioned on 可能会有帮助。 使用 ShellFile.FromFilePath(FilePath).Thumbnail.BitmapSource 作为文件和 使用 ShellFolder.FromParsingName(FolderPath).Thumbnail.BitmapSource 作为文件夹。