This works for me in my projects, hope this helps someone.
This is C # with P / Invokes, it will still work on x86 / x64 systems with WinXP.
(Shell.cs)
using System; using System.Drawing; using System.IO; using System.Runtime.InteropServices; namespace IconExtraction { internal sealed class Shell : NativeMethods { #region OfExtension ///<summary> /// Get the icon of an extension ///</summary> ///<param name="filename">filename</param> ///<param name="overlay">bool symlink overlay</param> ///<returns>Icon</returns> public static Icon OfExtension(string filename, bool overlay = false) { string filepath; string[] extension = filename.Split('.'); string dirpath = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "cache"); Directory.CreateDirectory(dirpath); if (String.IsNullOrEmpty(filename) || extension.Length == 1) { filepath = Path.Combine(dirpath, "dummy_file"); } else { filepath = Path.Combine(dirpath, String.Join(".", "dummy", extension[extension.Length - 1])); } if (File.Exists(filepath) == false) { File.Create(filepath); } Icon icon = OfPath(filepath, true, true, overlay); return icon; } #endregion #region OfFolder ///<summary> /// Get the icon of an extension ///</summary> ///<returns>Icon</returns> ///<param name="overlay">bool symlink overlay</param> public static Icon OfFolder(bool overlay = false) { string dirpath = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "cache", "dummy"); Directory.CreateDirectory(dirpath); Icon icon = OfPath(dirpath, true, true, overlay); return icon; } #endregion #region OfPath ///<summary> /// Get the normal,small assigned icon of the given path ///</summary> ///<param name="filepath">physical path</param> ///<param name="small">bool small icon</param> ///<param name="checkdisk">bool fileicon</param> ///<param name="overlay">bool symlink overlay</param> ///<returns>Icon</returns> public static Icon OfPath(string filepath, bool small = true, bool checkdisk = true, bool overlay = false) { Icon clone; SHGFI_Flag flags; SHFILEINFO shinfo = new SHFILEINFO(); if (small) { flags = SHGFI_Flag.SHGFI_ICON | SHGFI_Flag.SHGFI_SMALLICON; } else { flags = SHGFI_Flag.SHGFI_ICON | SHGFI_Flag.SHGFI_LARGEICON; } if (checkdisk == false) { flags |= SHGFI_Flag.SHGFI_USEFILEATTRIBUTES; } if (overlay) { flags |= SHGFI_Flag.SHGFI_LINKOVERLAY; } if (SHGetFileInfo(filepath, 0, ref shinfo, Marshal.SizeOf(shinfo), flags) == 0) { throw (new FileNotFoundException()); } Icon tmp = Icon.FromHandle(shinfo.hIcon); clone = (Icon)tmp.Clone(); tmp.Dispose(); if (DestroyIcon(shinfo.hIcon) != 0) { return clone; } return clone; } #endregion } }
(NativeMethods.cs)
using System; using System.Drawing; using System.Runtime.InteropServices; namespace IconExtraction { internal class NativeMethods { public struct SHFILEINFO { public IntPtr hIcon; public int iIcon; public uint dwAttributes; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDisplayName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)] public string szTypeName; }; [DllImport("user32.dll")] public static extern int DestroyIcon(IntPtr hIcon); [DllImport("shell32.dll", CharSet = CharSet.Auto, BestFitMapping = false, ThrowOnUnmappableChar = true)] public static extern IntPtr ExtractIcon(IntPtr hInst, string lpszExeFileName, int nIconIndex); [DllImport("Shell32.dll", BestFitMapping = false, ThrowOnUnmappableChar = true)] public static extern int SHGetFileInfo(string pszPath, int dwFileAttributes, ref SHFILEINFO psfi, int cbFileInfo, SHGFI_Flag uFlags); [DllImport("Shell32.dll")] public static extern int SHGetFileInfo(IntPtr pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, int cbFileInfo, SHGFI_Flag uFlags); } public enum SHGFI_Flag : uint { SHGFI_ATTR_SPECIFIED = 0x000020000, SHGFI_OPENICON = 0x000000002, SHGFI_USEFILEATTRIBUTES = 0x000000010, SHGFI_ADDOVERLAYS = 0x000000020, SHGFI_DISPLAYNAME = 0x000000200, SHGFI_EXETYPE = 0x000002000, SHGFI_ICON = 0x000000100, SHGFI_ICONLOCATION = 0x000001000, SHGFI_LARGEICON = 0x000000000, SHGFI_SMALLICON = 0x000000001, SHGFI_SHELLICONSIZE = 0x000000004, SHGFI_LINKOVERLAY = 0x000008000, SHGFI_SYSICONINDEX = 0x000004000, SHGFI_TYPENAME = 0x000000400 } }