Get icon 128*128 File type C#

前端 未结 1 924
梦如初夏
梦如初夏 2021-01-07 13:31

I need to get the icon of a file type doc or txt

It\'s size should be 128*128 and be saved as an png or ico file in good quality.

I used

Ic         


        
1条回答
  •  隐瞒了意图╮
    2021-01-07 13:46

    There is no icon-size 128x128 available from the Shell API SHGetImageList. The sizes range from the Win95 era of 16x16 and 32x32 via XP's 48x48 and finally Vista that added the 256x256 size.

    To get a png file from any of the available icon sizes I followed the blog How do I get a high resolution icon for a file from Raymond Chen. I ported his code to c# where I borrowed pieces from this answer.

    To follow Raymond's article here are the main two functions you need:

        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
        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;
        }
    

    The method GetIconIndex calls into the native SHGetFileIfo to get the icon index for the file (or extension) you provided in the name parameter.

    To get the actual icon the method GetJumboIcon calls the native SHGetImageList with a size attribute.

    To let it all work you combine the calls like so:

    IntPtr hIcon = GetJumboIcon(GetIconIndex("*.txt"));
    
    // from native to managed
    using (Icon ico = (Icon)System.Drawing.Icon.FromHandle(hIcon).Clone())
    {
        // save to file (or show in a picture box)
        ico.ToBitmap().Save("txticon.png", ImageFormat.Png);
    }
    Shell32.DestroyIcon(hIcon); // don't forget to cleanup
    

    To get an 48x48 icon you can extend the code with this method:

        // 48X48
        IntPtr GetXLIcon(int iImage)
        {
            IImageList spiml = null;
            Guid guil = new Guid(IID_IImageList);//or IID_IImageList
    
            Shell32.SHGetImageList(Shell32.SHIL_EXTRALARGE, ref guil, ref spiml);
            IntPtr hIcon = IntPtr.Zero;
            spiml.GetIcon(iImage, Shell32.ILD_TRANSPARENT | Shell32.ILD_IMAGE, ref hIcon); //
    
            return hIcon;
        }
    

    Due to interaction with unmanaged code you need to compile the project with the /unsafe option enabled. You can set that from visual studio by changing the project properties, goto to the Build tab and put a checkmark for the Allow unsafe code option. See this question why that is needed and here is the official MSDN documentation

    Native wrapper

    To call the native win32 api the functions and structures are wrapped in a static class that you need to include as well in your project. Most of those wrappers and the structures can be found at Pinvoke.net

    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
        );
    }
    

    Native structures

    [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);
    };
    

    0 讨论(0)
提交回复
热议问题