using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;
namespace ExtractBase64ExtIcon
{
    class Program
    {
        //Working example as of 2017/05/19 on windows 10 x64
        //example found here.
        //http://stackoverflow.com/a/28530403/1572750
        public string Extract(string extension)
        {
            var ext =  extension;
            IntPtr hIcon = GetJumboIcon(GetIconIndex("*." + ext));
            // from native to managed
             using (Icon ico = (Icon)Icon.FromHandle(hIcon).Clone())
             {
                 
               ImageConverter vert = new ImageConverter();
               byte[] data = (byte[])vert.ConvertTo(ico.ToBitmap(), typeof(byte[]));
               
               iconImage = Convert.ToBase64String(data);                 
             }
             Shell32.DestroyIcon(hIcon); // don't forget to cleanup
             return iconImage;
        }
        static int GetIconIndex(string pszFile)
        {
            SHFILEINFO sfi = new SHFILEINFO();
            Shell32.SHGetFileInfo(pszFile
                , 0
                , ref sfi
                , (uint)System.Runtime.InteropServices.Marshal.SizeOf(sfi)
                , (uint)(SHGFI.SysIconIndex | SHGFI.LargeIcon | SHGFI.UseFileAttributes));
            return sfi.iIcon;
        }
        // 256*256
        static IntPtr GetJumboIcon(int iImage)
        {
            IImageList spiml = null;
            Guid guil = new Guid(IID_IImageList2);//or IID_IImageList
            Shell32.SHGetImageList(Shell32.SHIL_JUMBO, ref guil, ref spiml);
            IntPtr hIcon = IntPtr.Zero;
            spiml.GetIcon(iImage, Shell32.ILD_TRANSPARENT | Shell32.ILD_IMAGE, ref hIcon); 
            return hIcon;
        }
        const string IID_IImageList = "46EB5926-582E-4017-9FDF-E8998DAA0950";
        const string IID_IImageList2 = "192B9D83-50FC-457B-90A0-2B82A8B5DAE1";
        public static class Shell32
        {
            public const int SHIL_LARGE = 0x0;
            public const int SHIL_SMALL = 0x1;
            public const int SHIL_EXTRALARGE = 0x2;
            public const int SHIL_SYSSMALL = 0x3;
            public const int SHIL_JUMBO = 0x4;
            public const int SHIL_LAST = 0x4;
            public const int ILD_TRANSPARENT = 0x00000001;
            public const int ILD_IMAGE = 0x00000020;
            [DllImport("shell32.dll", EntryPoint = "#727")]
            public extern static int SHGetImageList(int iImageList, ref Guid riid, ref IImageList ppv);
            [DllImport("user32.dll", EntryPoint = "DestroyIcon", SetLastError = true)]
            public static unsafe extern int DestroyIcon(IntPtr hIcon);
            [DllImport("shell32.dll")]
            public static extern uint SHGetIDListFromObject([MarshalAs(UnmanagedType.IUnknown)] object iUnknown, out IntPtr ppidl);
            [DllImport("Shell32.dll")]
            public static extern IntPtr SHGetFileInfo(
                string pszPath,
                uint dwFileAttributes,
                ref SHFILEINFO psfi,
                uint cbFileInfo,
                uint uFlags
            );
        }
        [Flags]
        enum SHGFI : uint
        {
            /// get icon
            Icon = 0x000000100,
            /// get display name
            DisplayName = 0x000000200,
            /// get type name
            TypeName = 0x000000400,
            /// get attributes
            Attributes = 0x000000800,
            /// get icon location
            IconLocation = 0x000001000,
            /// return exe type
            ExeType = 0x000002000,
            /// get system icon index
            SysIconIndex = 0x000004000,
            /// put a link overlay on icon
            LinkOverlay = 0x000008000,
            /// show icon in selected state
            Selected = 0x000010000,
            /// get only specified attributes
            Attr_Specified = 0x000020000,
            /// get large icon
            LargeIcon = 0x000000000,
            /// get small icon
            SmallIcon = 0x000000001,
            /// get open icon
            OpenIcon = 0x000000002,
            /// get shell size icon
            ShellIconSize = 0x000000004,
            /// pszPath is a pidl
            PIDL = 0x000000008,
            /// use passed dwFileAttribute
            UseFileAttributes = 0x000000010,
            /// apply the appropriate overlays
            AddOverlays = 0x000000020,
            /// Get the index of the overlay in the upper 8 bits of the iIcon
            OverlayIndex = 0x000000040,
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct SHFILEINFO
        {
            public const int NAMESIZE = 80;
            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;
        };
        [StructLayout(LayoutKind.Sequential)]
        public struct RECT
        {
            public int left, top, right, bottom;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            int x;
            int y;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct IMAGELISTDRAWPARAMS
        {
            public int cbSize;
            public IntPtr himl;
            public int i;
            public IntPtr hdcDst;
            public int x;
            public int y;
            public int cx;
            public int cy;
            public int xBitmap;    // x offest from the upperleft of bitmap
            public int yBitmap;    // y offset from the upperleft of bitmap
            public int rgbBk;
            public int rgbFg;
            public int fStyle;
            public int dwRop;
            public int fState;
            public int Frame;
            public int crEffect;
        }
        [StructLayout(LayoutKind.Sequential)]
        public struct IMAGEINFO
        {
            public IntPtr hbmImage;
            public IntPtr hbmMask;
            public int Unused1;
            public int Unused2;
            public RECT rcImage;
        }
        [ComImportAttribute()]
        [GuidAttribute("46EB5926-582E-4017-9FDF-E8998DAA0950")]
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IImageList
        {
            [PreserveSig]
            int Add(
            IntPtr hbmImage,
            IntPtr hbmMask,
            ref int pi);
            [PreserveSig]
            int ReplaceIcon(
            int i,
            IntPtr hicon,
            ref int pi);
            [PreserveSig]
            int SetOverlayImage(
            int iImage,
            int iOverlay);
            [PreserveSig]
            int Replace(
            int i,
            IntPtr hbmImage,
            IntPtr hbmMask);
            [PreserveSig]
            int AddMasked(
            IntPtr hbmImage,
            int crMask,
            ref int pi);
            [PreserveSig]
            int Draw(
            ref IMAGELISTDRAWPARAMS pimldp);
            [PreserveSig]
            int Remove(int i);
            [PreserveSig]
            int GetIcon(
            int i,
            int flags,
            ref IntPtr picon);
            [PreserveSig]
            int GetImageInfo(
            int i,
            ref IMAGEINFO pImageInfo);
            [PreserveSig]
            int Copy(
            int iDst,
            IImageList punkSrc,
            int iSrc,
            int uFlags);
            [PreserveSig]
            int Merge(
            int i1,
            IImageList punk2,
            int i2,
            int dx,
            int dy,
            ref Guid riid,
            ref IntPtr ppv);
            [PreserveSig]
            int Clone(
            ref Guid riid,
            ref IntPtr ppv);
            [PreserveSig]
            int GetImageRect(
            int i,
            ref RECT prc);
            [PreserveSig]
            int GetIconSize(
            ref int cx,
            ref int cy);
            [PreserveSig]
            int SetIconSize(
            int cx,
            int cy);
            [PreserveSig]
            int GetImageCount(ref int pi);
            [PreserveSig]
            int SetImageCount(
            int uNewCount);
            [PreserveSig]
            int SetBkColor(
            int clrBk,
            ref int pclr);
            [PreserveSig]
            int GetBkColor(
            ref int pclr);
            [PreserveSig]
            int BeginDrag(
            int iTrack,
            int dxHotspot,
            int dyHotspot);
            [PreserveSig]
            int EndDrag();
            [PreserveSig]
            int DragEnter(
            IntPtr hwndLock,
            int x,
            int y);
            [PreserveSig]
            int DragLeave(
            IntPtr hwndLock);
            [PreserveSig]
            int DragMove(
            int x,
            int y);
            [PreserveSig]
            int SetDragCursorImage(
            ref IImageList punk,
            int iDrag,
            int dxHotspot,
            int dyHotspot);
            [PreserveSig]
            int DragShowNolock(
            int fShow);
            [PreserveSig]
            int GetDragImage(
            ref POINT ppt,
            ref POINT pptHotspot,
            ref Guid riid,
            ref IntPtr ppv);
            [PreserveSig]
            int GetItemFlags(
            int i,
            ref int dwFlags);
            [PreserveSig]
            int GetOverlayImage(
            int iOverlay,
            ref int piIndex);
        };
    }
}