/// <summary>
        /// Extract the icon from file giving an index.
        /// </summary>
        /// <param name="path">Path to file.</param>
        /// <param name="index">Icon index.</param>
        /// <returns>This method always returns an icon.</returns>
        public static Icon ExtractIconFromFile(string path, int index)
        {
            //Win32
            //Extract the icon handle
            IntPtr hIcon = Shell32.ExtractIcon(Process.GetCurrentProcess().Handle, Environment.ExpandEnvironmentVariables(path), index);

            //Get icon form .dll or .exe
            if (hIcon == IntPtr.Zero)
            {
                return(null);
            }
            return(GetManagedIcon(hIcon));
        }
        /// <summary>
        /// Extract the icon from file.
        /// </summary>
        /// <param name="path">File path,
        /// such as ex: "C:\\Program Files\\NetMeeting\\conf.exe,1".</param>
        /// <param name="isLarge">
        /// Determines the returned icon is a large (may be 32x32 px)
        /// or small icon (16x16 px).</param>
        public static Icon ExtractIconFromFile(string path, bool isLarge)
        {
            IntPtr[] hDummy  = new IntPtr[] { IntPtr.Zero };
            IntPtr[] hIconEx = new IntPtr[] { IntPtr.Zero };

            try
            {
                EmbeddedIconInfo embeddedIcon  = GetEmbeddedIconInfo(Environment.ExpandEnvironmentVariables(path));
                uint             readIconCount = isLarge ? Shell32.ExtractIconEx(embeddedIcon.FileName, 0, hIconEx, hDummy, 1) : Shell32.ExtractIconEx(embeddedIcon.FileName, 0, hDummy, hIconEx, 1);
                if (readIconCount > 0 && hIconEx[0] != IntPtr.Zero)
                {
                    // Get first icon.
                    return(GetManagedIcon(hIconEx[0]));
                }
                else // No icon read
                {
                    return(null);
                }
            }
            catch (Exception exc)
            {
                // Extract icon error.
                throw new ApplicationException("Could not extract icon", exc);
            }
            finally
            {
                // Release resources.
                foreach (IntPtr ptr in hIconEx)
                {
                    if (ptr != IntPtr.Zero)
                    {
                        User32.DestroyIcon(ptr);
                    }
                }
                foreach (IntPtr ptr in hDummy)
                {
                    if (ptr != IntPtr.Zero)
                    {
                        User32.DestroyIcon(ptr);
                    }
                }
            }
        }
        /// <summary>
        /// Used to access system folder icons.
        /// </summary>
        /// <param name="size">Specify large or small icons.</param>
        /// <param name="folderType">Specify open or closed FolderType.</param>
        /// <param name="shfi">Return Folder Information</param>
        /// <returns>System.Drawing.Icon</returns>
        public static Icon GetFolderIcon(IconSize size, FolderType folderType, ref Shell32.SHFILEINFO shfi)
        {
            // Need to add size check, although errors generated at present!
            Shell32.SHGetFileInfoConstants flags = Shell32.SHGetFileInfoConstants.SHGFI_TYPENAME | Shell32.SHGetFileInfoConstants.SHGFI_DISPLAYNAME | Shell32.SHGetFileInfoConstants.SHGFI_ICON | Shell32.SHGetFileInfoConstants.SHGFI_USEFILEATTRIBUTES;

            if (FolderType.Open == folderType)
            {
                flags |= Shell32.SHGetFileInfoConstants.SHGFI_OPENICON;
            }

            if (IconSize.Small == size)
            {
                flags |= Shell32.SHGetFileInfoConstants.SHGFI_SMALLICON;
            }
            else
            {
                flags |= Shell32.SHGetFileInfoConstants.SHGFI_LARGEICON;
            }

            IntPtr hIml;

            // Get the folder icon
            shfi = new Shell32.SHFILEINFO();
            if (IconHelper.Utils.IsSevenOrAbove()) // Windows 7 FIX
            {
                hIml = Shell32.SHGetFileInfo(Environment.GetFolderPath(Environment.SpecialFolder.System),
                                             Shell32.FILE_ATTRIBUTE.DIRECTORY,
                                             ref shfi,
                                             (uint)Marshal.SizeOf(shfi),
                                             flags);
            }
            else
            {
                hIml = Shell32.SHGetFileInfo(null,
                                             Shell32.FILE_ATTRIBUTE.DIRECTORY,
                                             ref shfi,
                                             (uint)Marshal.SizeOf(shfi),
                                             flags);
            }
            if (shfi.hIcon == IntPtr.Zero)
            {
                return(null);
            }
            if (!IconHelper.Utils.IsXpOrAbove())
            {
                return(GetManagedIcon(shfi.hIcon));
            }
            // Get the System IImageList object from the Shell:
            Guid iidImageList = new Guid("46EB5926-582E-4017-9FDF-E8998DAA0950");

            Shell32.IImageList iImageList = null;
            int ret = Shell32.SHGetImageList(
                (int)size,
                ref iidImageList,
                ref iImageList
                );

            // the image list handle is the IUnknown pointer, but
            // using Marshal.GetIUnknownForObject doesn't return
            // the right value.  It really doesn't hurt to make
            // a second call to get the handle:
            Shell32.SHGetImageListHandle((int)size, ref iidImageList, ref hIml);
            IntPtr hIcon = IntPtr.Zero;

            if (iImageList == null)
            {
                hIcon = Comctl32.ImageList_GetIcon(
                    hIml,
                    shfi.iIcon,
                    (int)Comctl32.ImageListDrawItemConstants.ILD_TRANSPARENT);
            }
            else
            {
                iImageList.GetIcon(
                    shfi.iIcon,
                    (int)Comctl32.ImageListDrawItemConstants.ILD_TRANSPARENT,
                    ref hIcon);
            }
            return(hIcon == IntPtr.Zero ? GetManagedIcon(shfi.hIcon) : GetManagedIcon(hIcon));
        }
        /// <summary>
        /// Returns an icon for a given file - indicated by the name parameter.
        /// </summary>
        /// <param name="name">Extension or pathname for file.</param>
        /// <param name="size">Large or small</param>
        /// <param name="linkOverlay">Whether to include the link icon</param>
        /// <param name="shfi">Return File Information</param>
        /// <returns>System.Drawing.Icon</returns>
        public static Icon GetFileIcon(string name, IconSize size, bool linkOverlay, ref Shell32.SHFILEINFO shfi)
        {
            name = Environment.ExpandEnvironmentVariables(name);
            shfi = new Shell32.SHFILEINFO();
            Shell32.SHGetFileInfoConstants flags = Shell32.SHGetFileInfoConstants.SHGFI_TYPENAME | Shell32.SHGetFileInfoConstants.SHGFI_DISPLAYNAME | Shell32.SHGetFileInfoConstants.SHGFI_ICON | Shell32.SHGetFileInfoConstants.SHGFI_SHELLICONSIZE | Shell32.SHGetFileInfoConstants.SHGFI_SYSICONINDEX | Shell32.SHGetFileInfoConstants.SHGFI_USEFILEATTRIBUTES;

            if (linkOverlay)
            {
                flags |= Shell32.SHGetFileInfoConstants.SHGFI_LINKOVERLAY;
            }
            /* Check the size specified for return. */
            if (IconSize.Small == size)
            {
                flags |= Shell32.SHGetFileInfoConstants.SHGFI_SMALLICON;
            }
            else
            {
                flags |= Shell32.SHGetFileInfoConstants.SHGFI_LARGEICON;
            }

            IntPtr hIml = Shell32.SHGetFileInfo(name,
                                                Shell32.FILE_ATTRIBUTE.NORMAL,
                                                ref shfi,
                                                (uint)Marshal.SizeOf(shfi),
                                                flags);

            if (shfi.hIcon == IntPtr.Zero)
            {
                return(null);
            }
            if (!IconHelper.Utils.IsXpOrAbove())
            {
                return(GetManagedIcon(shfi.hIcon));
            }
            // Get the System IImageList object from the Shell:
            Guid iidImageList = new Guid("46EB5926-582E-4017-9FDF-E8998DAA0950");

            Shell32.IImageList iImageList = null;
            int ret = Shell32.SHGetImageList(
                (int)size,
                ref iidImageList,
                ref iImageList
                );

            // the image list handle is the IUnknown pointer, but
            // using Marshal.GetIUnknownForObject doesn't return
            // the right value.  It really doesn't hurt to make
            // a second call to get the handle:
            Shell32.SHGetImageListHandle((int)size, ref iidImageList, ref hIml);

            IntPtr hIcon = IntPtr.Zero;

            if (iImageList == null)
            {
                hIcon = Comctl32.ImageList_GetIcon(
                    hIml,
                    shfi.iIcon,
                    (int)Comctl32.ImageListDrawItemConstants.ILD_TRANSPARENT);
            }
            else
            {
                iImageList.GetIcon(
                    shfi.iIcon,
                    (int)Comctl32.ImageListDrawItemConstants.ILD_TRANSPARENT,
                    ref hIcon);
            }
            return(hIcon == IntPtr.Zero ? GetManagedIcon(shfi.hIcon) : GetManagedIcon(hIcon));
        }
 /// <summary>
 /// Get total icons on a file
 /// </summary>
 /// <param name="path">Path to a file</param>
 /// <example>
 /// <code>IconReader.GetTotalIcons("C:\\Windows\\system32\\shell32.dll");</code>
 /// </example>
 /// <returns>Total icon on selected file</returns>
 public static uint GetTotalIcons(string path)
 {
     return(Shell32.ExtractIconEx(Environment.ExpandEnvironmentVariables(path), -1, null, null, 0));
 }
        /// <summary>
        /// Extract all icons from a file
        /// </summary>
        /// <param name="path">File path</param>
        /// <param name="isLarge">Large (32x32) or Small (16x16) icon</param>
        /// <returns>Icon[] array</returns>
        public static Icon[] ExtractIconsFromFile(string path, bool isLarge)
        {
            path = Environment.ExpandEnvironmentVariables(path);
            int iconsCount = (int)GetTotalIcons(path);

            //checks how many icons.

            IntPtr[] iconPtr = new IntPtr[iconsCount];

            //extracts the icons by the size that was selected.

            uint readIconCount = isLarge ? Shell32.ExtractIconEx(path, 0, iconPtr, null, iconsCount) : Shell32.ExtractIconEx(path, 0, null, iconPtr, iconsCount);

            Icon[] iconList = new Icon[iconsCount];

            //gets the icons in a list.

            for (int i = 0; i < iconsCount; i++)
            {
                if (iconPtr[i] != IntPtr.Zero)
                {
                    iconList[i] = GetManagedIcon(iconPtr[i]);
                }
            }
            return(iconList);
        }