c#获取文件超大图标256*256(转)

yizhihongxing

C#获取文件超大图标256*256(转)

在开发工程中,我们经常会需要获取文件的图标,以便在自定义的程序中进行显示。通常情况下,我们可以通过Shell32库中的SHGetFileInfo函数实现。但是在Windows Vista及以上操作系统中,系统引入了超大图标(256*256)的支持,而SHGetFileInfo无法获取超大图标。本文将介绍如何使用C#获取文件的超大图标。

Windows API

在了解获取超大图标之前,我们需要先了解几个Windows API。这些API用于Windows Shell操作,以及获取资源的相关信息。

SHGetStockIconInfo函数

这个函数用于获取Windows Stock Icon(Windows自带的一些标准图标),其中参数_In_传入的SHSTOCKICONID枚举值确定我们要获取哪个Stock Icon。另外,参数_Out_传出的结构体SHSTOCKICONINFO包含了获取到的图标的信息。

[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SHSTOCKICONINFO
{
    public UInt32 cbSize;
    public IntPtr hIcon;
    public int iSysImageIndex;
    public int iIcon;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
    public string szPath;

    public SHSTOCKICONINFO(UInt32 size) : this()
    {
        cbSize = size;
    }
}

public enum SHSTOCKICONID : uint
{
    SIID_DOCNOASSOC = 0,
    SIID_DOCASSOC = 1,
    SIID_APPLICATION = 2,
    SIID_FOLDER = 3,
    SIID_FOLDEROPEN = 4,
    SIID_DRIVE525 = 5,
    SIID_DRIVE35 = 6,
    SIID_DRIVEREMOVE = 7,
    SIID_DRIVEFIXED = 8,
    SIID_DRIVENET = 9,
    SIID_DRIVENETDISABLED = 10,
    SIID_DRIVECD = 11,
    SIID_DRIVERAM = 12,
    SIID_WORLD = 13,
    SIID_SERVER = 15,
    SIID_PRINTER = 16,
    SIID_MYNETWORK = 17,
    SIID_FIND = 22,
    SIID_HELP = 23,
    SIID_SHARE = 28,
    SIID_LINK = 29,
    SIID_SLOWFILE = 30,
    SIID_RECYCLER = 31,
    SIID_RECYCLERFULL = 32,
    SIID_MEDIACDAUDIO = 40,
    SIID_LOCK = 47,
    SIID_AUTOLIST = 49,
    SIID_PRINTERNET = 50,
    SIID_SERVERSHARE = 51,
    SIID_PRINTERFAX = 52,
    SIID_PRINTERFAXNET = 53,
    SIID_PRINTERFILE = 54,
    SIID_STACK = 55,
    SIID_MEDIASVCD = 56,
    SIID_STUFFEDFOLDER = 57,
    SIID_DRIVEUNKNOWN = 58,
    SIID_DRIVEDVD = 59,
    SIID_MEDIADVD = 60,
    SIID_MEDIADVDRAM = 61,
    SIID_MEDIADVDRW = 62,
    SIID_MEDIADVDR = 63,
    SIID_MEDIADVDROM = 64,
    SIID_MEDIACDAUDIOPLUS = 65,
    SIID_MEDIACDRW = 66,
    SIID_MEDIACDR = 67,
    SIID_MEDIACDBURN = 68,
    SIID_MEDIABLANKCD = 69,
    SIID_MEDIACDROM = 70,
    SIID_AUDIOFILES = 71,
    SIID_IMAGEFILES = 72,
    SIID_VIDEOFILES = 73,
    SIID_MIXEDFILES = 74,
    SIID_FOLDERBACK = 75,
    SIID_FOLDERFRONT = 76,
    SIID_SHIELD = 77,
    SIID_WARNING = 78,
    SIID_INFO = 79,
    SIID_ERROR = 80,
    SIID_KEY = 81,
    SIID_SOFTWARE = 82,
    SIID_RENAME = 83,
    SIID_DELETE = 84,
    SIID_MEDIAAUDIODVD = 85,
    SIID_MEDIAMOVIEDVD = 86,
    SIID_MEDIAENHANCEDCD = 87,
    SIID_MEDIAENHANCEDDVD = 88,
    SIID_MEDIAHDDVD = 89,
    SIID_MEDIABLURAY = 90,
    SIID_MEDIAVCD = 91,
    SIID_MEDIADVDPLUSR = 92,
    SIID_MEDIADVDPLUSRW = 93,
    SIID_DESKTOPPC = 94,
    SIID_MOBILEPC = 95,
    SIID_USERS = 96,
    SIID_MEDIANET = 97,
    SIID_UAVIDEO = 98,
    SIID_UATV = 99,
    SIID_MEDIAVIDEOCD = 100,
    SIID_MEDIAVIDEODVD = 101,
    SIID_MEDIATVCOMPUTER = 102,
    SIID_MEDIATV = 103,
    SIID_MEDIAAUDIOCD = 104,
    SIID_MEDIAAUDIOBOOK = 105,
    SIID_MEDIAMUSIC = 106,
    SIID_DEVICECELLPHONE = 107,
    SIID_DEVICECAMERA = 108,
    SIID_DEVICEVIDEOCAMERA = 109,
    SIID_DEVICEAUDIOPLAYER = 110,
    SIID_NETWORKCONNECT = 112,
    SIID_INTERNET = 113,
    SIID_ZIPFILE = 114,
    SIID_SETTINGS = 117,
    SIID_DRIVEHDDVD = 118,
    SIID_DRIVEBD = 119,
    SIID_MEDIAHDDVDROM = 120,
    SIID_MEDIAHDDVDR = 121,
    SIID_MEDIAHDDVDRAM = 122,
    SIID_MEDIABDROM = 123,
    SIID_MEDIABDR = 124,
    SIID_MEDIABDRE = 125,
    SIID_CLUSTEREDDRIVE = 126,
    SIID_MAX_ICONS = 175
}

[DllImport("Shell32.dll", SetLastError = true)]
public static extern int SHGetStockIconInfo(SHSTOCKICONID siid, uint uFlags, ref SHSTOCKICONINFO psii);

SHCreateItemFromParsingName函数

这个函数用于根据文件路径创建IShellItem实例。我们可以通过该接口获取文件的超大图标。

[ComImportAttribute()]
[GuidAttribute("43826D1E-E718-42EE-BC55-A1E261C37BFE")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
public interface IShellItem
{
    void BindToHandler(IntPtr pbc, [MarshalAs(UnmanagedType.LPStruct)] Guid bhid, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IntPtr ppv);
    void GetParent(out IShellItem ppsi);
    void GetDisplayName(uint sigdnName, out IntPtr ppszName);
    void GetAttributes(uint sfgaoMask, out uint psfgaoAttribs);
    void Compare(IShellItem psi, uint hint, out int piOrder);
}

[DllImport("shell32.dll", CharSet = CharSet.Unicode, PreserveSig = false)]
public static extern void SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string file, IntPtr pbc, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, [MarshalAs(UnmanagedType.Interface)] out IShellItem ppv);

获取超大图标

获取文件的超大图标需要用到IShellItemImageFactory接口,该接口提供了获取Item Image的方法。

我们首先需要通过文件路径创建IShellItem实例,然后利用IShellItemImageFactory获取超大图标。

public static BitmapSource GetLargeIcon(string fileName)
{
    SHCreateItemFromParsingName(fileName, IntPtr.Zero, typeof(IShellItem).GUID, out IShellItem nativeShellItem);
    IntPtr shellItemPtr = Marshal.GetComInterfaceForObject(nativeShellItem, typeof(IShellItem));
    IntPtr shellItemImageFactoryPtr = IntPtr.Zero;
    Guid shellItemImageFactoryGuid = new Guid("bcc18b79-ba16-442f-80c4-8a59c30c463b");

    try
    {
        Marshal.QueryInterface(shellItemPtr, ref shellItemImageFactoryGuid, out shellItemImageFactoryPtr);
        IShellItemImageFactory shellItemImageFactory = (IShellItemImageFactory)Marshal.GetObjectForIUnknown(shellItemImageFactoryPtr);

        uint iconSize = 256;
        System.Runtime.InteropServices.ComTypes.FILETIME ft = new System.Runtime.InteropServices.ComTypes.FILETIME();
        IntPtr hBitmap = IntPtr.Zero;

        shellItemImageFactory.GetImage(new SIZE()
        {
            cx = (int)iconSize,
            cy = (int)iconSize
        }, 0x0, ref ft, out hBitmap);

        if (hBitmap != IntPtr.Zero)
        {
            return Imaging.CreateBitmapSourceFromHBitmap(hBitmap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromWidthAndHeight((int)iconSize, (int)iconSize));
        }

        return null;
    }
    finally
    {
        Marshal.ReleaseComObject(nativeShellItem);
        if (shellItemImageFactoryPtr != IntPtr.Zero)
        {
            Marshal.Release(shellItemImageFactoryPtr);
        }
    }
}

结语

通过以上实现,我们可以在Windows Vista及以上操作系统中获取文件的超大图标。同时,我们也了解到了相关的Windows API,并可以借鉴其中的方法来实现其他功能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:c#获取文件超大图标256*256(转) - Python技术站

(0)
上一篇 2023年3月28日
下一篇 2023年3月28日

相关文章

  • Onenote笔记本怎么添加加载项?

    当你使用OneNote软件的时候,你可能需要添加一些加载项来增加工作的效率和便利性。本文将为你详细讲解如何添加Onenote笔记本加载项。 步骤一:打开Onenote软件 首先,你需要从你的计算机上打开Onenote软件。 步骤二:找到“文件”选项 在Onenote的主界面上,你可以看到一个名为“文件”的选项。 步骤三:选择“选项” 在“文件”选项下,你可以…

    other 2023年6月25日
    00
  • xml验证器

    XML验证器 XML (可扩展标记语言) 是一种广泛使用的标记语言,用于在Web应用程序和其他数据交换应用程序之间共享数据。但是,手动验证XML文档是否符合特定的格式可能是非常耗时和困难的。 为了解决这个问题,XML验证器被开发出来,可以自动检测XML文档中的错误,并快速定位并修复问题。在本文中,我们将介绍XML验证器的一些基本知识和如何使用它来验证XML文…

    其他 2023年3月28日
    00
  • [Asp.Net Core]提高开发效率的方法

    提高开发效率的方法 在Asp.Net Core开发中,有一些方法可以帮助提高开发效率。下面是一些可以考虑的方法和示例说明: 1. 使用代码生成工具 代码生成工具可以帮助自动生成重复性的代码,减少手动编写的工作量。一个常用的代码生成工具是Scaffolding,它可以根据数据库模型自动生成控制器、视图和数据访问层代码。 示例说明: dotnet aspnet-…

    other 2023年7月27日
    00
  • Android 启动模式详细介绍

    Android 启动模式详细介绍 在Android开发中,启动模式是指定义了一个Activity如何启动和运行的规则。了解和正确使用启动模式可以帮助我们更好地管理Activity的生命周期和任务栈。下面是Android中常用的四种启动模式: 1. Standard(标准模式) 标准模式是Android默认的启动模式。每次启动一个Activity时,系统都会创…

    other 2023年8月20日
    00
  • 迅雷9.1.23正式版(9.1.23.556)发布 附下载地址

    迅雷9.1.23正式版(9.1.23.556)发布 附下载地址攻略 迅雷是一款常用的下载工具,最新版本为9.1.23正式版(9.1.23.556)。本攻略将详细介绍如何下载和安装迅雷9.1.23正式版,并提供下载地址。 下载迅雷9.1.23正式版 你可以通过以下步骤下载迅雷9.1.23正式版: 打开你的浏览器,访问迅雷官方网站。 在官方网站的首页或下载页面上…

    other 2023年8月4日
    00
  • 轻松装win10:vmwareworkstation12虚拟机下载

    轻松装win10:vmwareworkstation12虚拟机下载 如果你想试用最新的Windows 10操作系统,但又不想在你的电脑上直接安装它,那么使用虚拟机是一个不错的选择,它可以让你在安全的环境下尝试新的操作系统。VMware Workstation 12就是这样一个强大的虚拟机软件,它可以帮助你轻松地在你的计算机上运行多个虚拟操作系统,包括Wind…

    其他 2023年3月28日
    00
  • MAGIX Sound Forge Pro 12 Suite破解版安装教程+补丁激活图文详解(附下载)

    很抱歉,我无法提供关于软件破解的指导或支持。这种行为违反了软件的使用许可协议,并且可能涉及非法活动。我鼓励您遵守法律和道德准则,购买正版软件并按照它们的官方安装指南进行操作。如果您有任何其他问题或需要其他帮助,请随时告诉我。

    other 2023年9月6日
    00
  • Python面向对象程序设计OOP入门教程【类,实例,继承,重载等】

    Python面向对象程序设计OOP入门教程 什么是面向对象编程 面向对象编程(Object Oriented Programming,OOP)是一种常用的编程思想和方法。它把现实世界中的事物看作对象,通过封装、继承、多态等概念来描述对象及其之间的关系,以进一步实现程序的模块化、复用、扩展和维护。 在 Python 中,一切事物都是对象。Python 中的面向…

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部