获取图标 128*128 文件类型 C#

Get icon 128*128 File type C#

我需要获取文件类型 doc 或 txt 的图标

它的大小应该是128*128,并保存为质量好的png或ico文件。

我用过

Icon ico = Icon.ExtractAssociatedIcon(@"d:\1.txt");
pictureBox1.Image = ico.ToBitmap();

并保存pictureBox1中的图片,但是那个尺寸是32*32。

我很想要128*128的尺寸。

我该怎么做?

ShellAPISHGetImageList 没有可用的 128x128 图标。尺寸范围从Win95时代的16x16和32x32到XP的48x48,最后Vista增加了256x256尺寸。

要从任何可用的图标尺寸中获取 png 文件,我遵循了 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

要遵循 Raymond 的文章,这里是您需要的主要两个函数:

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

GetIconIndex 方法调用本机 SHGetFileIfo 以获取您在名称参数中提供的文件(或扩展名)的图标索引。

要获取实际图标,方法 GetJumboIcon 调用具有大小属性​​的本机 SHGetImageList

为了让它全部正常工作,您可以像这样组合调用:

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

要获得 48x48 图标,您可以使用此方法扩展代码:

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

由于与非托管代码交互,您需要在启用 /unsafe 选项的情况下编译项目。您可以通过更改项目属性从 visual studio 设置它,转到“构建”选项卡并勾选 允许不安全代码 选项。参见 this question why that is needed and here is the official MSDN documentation

原生包装器

要调用本机 win32 api,函数和结构被包装在静态 class 中,您也需要将其包含在项目中。大多数包装器和结构都可以在 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
    );
}

原生结构

[Flags]
enum SHGFI : uint
{
    /// <summary>get icon</summary>
    Icon = 0x000000100,
    /// <summary>get display name</summary>
    DisplayName = 0x000000200,
    /// <summary>get type name</summary>
    TypeName = 0x000000400,
    /// <summary>get attributes</summary>
    Attributes = 0x000000800,
    /// <summary>get icon location</summary>
    IconLocation = 0x000001000,
    /// <summary>return exe type</summary>
    ExeType = 0x000002000,
    /// <summary>get system icon index</summary>
    SysIconIndex = 0x000004000,
    /// <summary>put a link overlay on icon</summary>
    LinkOverlay = 0x000008000,
    /// <summary>show icon in selected state</summary>
    Selected = 0x000010000,
    /// <summary>get only specified attributes</summary>
    Attr_Specified = 0x000020000,
    /// <summary>get large icon</summary>
    LargeIcon = 0x000000000,
    /// <summary>get small icon</summary>
    SmallIcon = 0x000000001,
    /// <summary>get open icon</summary>
    OpenIcon = 0x000000002,
    /// <summary>get shell size icon</summary>
    ShellIconSize = 0x000000004,
    /// <summary>pszPath is a pidl</summary>
    PIDL = 0x000000008,
    /// <summary>use passed dwFileAttribute</summary>
    UseFileAttributes = 0x000000010,
    /// <summary>apply the appropriate overlays</summary>
    AddOverlays = 0x000000020,
    /// <summary>Get the index of the overlay in the upper 8 bits of the iIcon</summary>
    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);
};