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

时间:2015-02-15 12:13:57

标签: c# c#-2.0

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

的图标

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

我用过

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

并保存pictureBox1中的图像,但该大小为32 * 32.

我真的想要128 * 128的尺码。

我该怎么做?

1 个答案:

答案 0 :(得分:18)

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

要从我blog How do I get a high resolution icon for a file Raymond Chen this answer后面的任何可用图标尺寸中获取png文件。我将他的代码移植到c#,我从SHGetFileIfo借了一些东西。

关注雷蒙德的文章,这里有你需要的两个主要功能:

    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调用本机SHGetImageList以获取您在name参数中提供的文件(或扩展名)的图标索引。

要获取实际图标,方法GetJumboIcon会调用带有尺寸属性的原生this question

要让它全部工作,你可以像这样组合调用:

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中进行设置,转到Build选项卡并勾选允许不安全的代码选项。请参阅here is the official MSDN documentation为何需要,Pinvoke.net

原生包装

要调用本机win32 api,函数和结构将包装在您需要包含在项目中的静态类中。大多数包装和结构都可以在{{3}}

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