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

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日

相关文章

  • mysql 替换字段部分内容及mysql 替换函数replace()

    MySQL 是一个广泛使用的关系型数据库管理系统,其中提供了很多适用于数据处理的函数。replace() 函数是 MySQL 中的一种函数,它可以用来替换掉某个字符串中的一部分内容,常用于处理字符串型字段的内容更新。 一、replace() 函数的基本用法 replace() 函数的基本用法如下: replace(str,from_str,to_str) 其…

    other 2023年6月25日
    00
  • Vue Router嵌套路由(children)的用法小结

    Vue Router嵌套路由(children)的用法小结 Vue Router是Vue.js官方的路由管理器,它允许我们在Vue应用中实现页面之间的导航和路由功能。其中,嵌套路由(children)是Vue Router提供的一个强大功能,它允许我们在一个路由下定义子路由,从而实现更复杂的页面结构和导航。 嵌套路由的基本用法 要使用嵌套路由,我们需要在Vu…

    other 2023年7月28日
    00
  • 5分钟内了解C语言的指针

    下面是“5分钟内了解C语言的指针”的完整攻略: 1. 理解指针的概念 指针是C语言中一种非常重要的数据类型,它允许我们直接访问计算机内存中的数据。指针变量存储了内存地址,通过这个地址可以找到对应的数据内容。我们可以使用符号 * 来定义和操作指针变量。 以下是在C语言中定义指针变量的一种方式: int *p; 这样定义的变量p是一个整型指针变量,它可以指向一个…

    other 2023年6月27日
    00
  • C语言中字符串常用函数strcat与strcpy的用法介绍

    标题:C语言中字符串常用函数strcat与strcpy的用法介绍 1. 简介 在C语言中,字符串是以一个字符数组的形式存储的。在对字符串进行各种操作时,常常需要用到字符串处理函数来完成操作。其中,strcat和strcpy函数是C语言中比较常用的字符串处理函数之一,本文即是要介绍这两个函数的用法。 1.1 strcat函数 函数原型:char *strcat…

    other 2023年6月20日
    00
  • css 样式加载的优先级使用经验分享

    来具体讲解一下 CSS 样式加载的优先级使用经验分享。 1. CSS 样式的优先级 CSS 样式有优先级之分,具体规则如下: 浏览器默认样式 < 外部样式表 < 内部样式表 < 行内样式 < !important 其中 !important 是最高优先级,会覆盖其他样式。 2. 使用经验分享 2.1. 建议使用外部样式表 外部样式表适…

    other 2023年6月25日
    00
  • 安卓手机开发者模式怎么开启?安卓手机开发者模式开启和关闭教程

    下面是详细的攻略: 什么是安卓手机开发者模式? 开发者模式是安卓手机中一个隐藏的系统设置选项,提供了许多高级选项和调试工具,能够帮助开发人员在测试、优化和开发应用程序时进行调试和分析。通常情况下,普通用户无需开启该选项。 如何开启安卓手机开发者模式? 点击手机的“设置”图标,滑动到底部,点击“关于手机”(或“关于设备”)选项。 在“关于手机”页面中找到“版本…

    other 2023年6月26日
    00
  • jquery实现加载更多”转圈圈”效果(示例代码)

    下面是详细的攻略。 1. 什么是“加载更多”功能? “加载更多”功能是指在页面上展现一部分数据,当用户滚动到页面底部时,自动加载更多数据,让用户可以无限滚动阅读。 2. 如何实现“加载更多”功能? 实现“加载更多”功能可以使用ajax技术和jquery库。ajax技术可以帮助我们在不刷新页面的情况下向服务器发送请求,jquery可以帮助我们方便地操作DOM元…

    other 2023年6月25日
    00
  • 8款不错的ci/cd工具

    以下是详细讲解“8款不错的CI/CD工具的完整攻略,过程中至少包含两条示例说明”的标准Markdown格式文本: 8款不错的CI/CD工具 CI/CD是指持续集成和持续交付,是现代软件开发中的重要环节。以下是8款不错的CI/CD工具,包括特点、用法和示例。 1. Jenkins Jenkins是一款开源的CI/CD工具,它支持种编程语言和操作系统。以下是Je…

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