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日

相关文章

  • 图片加载进度实时显示

    一、概述 在网页中加载图片是很常见的场景,但一些大图片、网络延迟等因素都会导致图片加载时间延长。在用户等待图片加载时,为了提升用户体验,可以通过实时显示图片加载进度来让用户了解当前图片加载的进度,从而缓解用户的焦虑感和等待时间。本文将详细介绍如何实现图片加载进度实时显示的功能。 二、实现方式 实时显示图片加载进度的方式一般有两种,分别是:使用canvas绘制…

    other 2023年6月25日
    00
  • 一段提取用户名和md5的vbs代码

    首先,我们来了解一下什么是vbs代码。VBScript是Microsoft Visual Basic Scripting Edition的缩写,是一种基于VB的脚本语言,用于Windows平台上的应用程序开发和系统管理。它可以与HTML、ASP、WMI等联合使用,广泛地应用于Web自动化测试、任务自动化和系统管理等领域。 现在,我们将解释一个提取用户名和md…

    other 2023年6月27日
    00
  • 微信小程序getphonenumber获取用户手机号

    微信小程序getPhoneNumber获取用户手机号攻略 微信小程序提供了getPhoneNumber接口,可以获取用户的手机号码。本文将详细介绍如何使用getPhoneNumber接口获取用户手机号,包括前置条件、调用流程、注意事项等。同时,本文还提供了两个示例说明,以帮助您更好地理解和应用这些技术。 前置条件 在使用getPhoneNumber接口获取用…

    other 2023年5月7日
    00
  • JAVA利用递归删除文件代码实例

    下面详细讲解一下“JAVA利用递归删除文件代码实例”的完整攻略。 1. 背景介绍 在Java的文件操作过程中,有时候需要删除文件或文件夹,为了保证删除的彻底性,我们可以使用递归来实现该过程。 2. 实现步骤 下面是JAVA利用递归删除文件代码的实现步骤: 首先判断要删除的文件或文件夹是否存在,如果不存在,则直接返回。 如果存在,则判断要删除的是文件还是文件夹…

    other 2023年6月27日
    00
  • win11 ip地址自动获取怎么设置?win11设置ip地址自动获取方法

    Win11 IP地址自动获取设置攻略 在Win11操作系统中,设置IP地址自动获取非常简单。下面是详细的步骤: 打开“设置”:点击任务栏上的“开始”按钮,然后点击“设置”图标(齿轮状图标)。 进入“网络和互联网”设置:在设置窗口中,点击左侧导航栏中的“网络和互联网”选项。 打开网络设置:在“网络和互联网”设置页面中,点击右侧的“高级网络设置”链接。 进入网络…

    other 2023年7月31日
    00
  • java内存管理关系及内存泄露的原理分析

    Java内存管理关系及内存泄露的原理分析 Java内存管理是Java程序设计中非常重要的一部分,它涉及到内存的分配、使用和释放。正确地管理内存可以提高程序的性能和稳定性,而内存泄露则可能导致程序的崩溃和性能下降。本文将详细讲解Java内存管理的关系以及内存泄露的原理,并提供两个示例来说明。 Java内存管理关系 Java内存管理主要涉及到以下几个方面: 堆(…

    other 2023年8月2日
    00
  • 看门狗2闪退怎么解决 看门狗闪退解决方案

    看门狗2闪退怎么解决?看门狗闪退解决方案 前言 《看门狗2》是一款由育碧公司制作的开放世界动作冒险游戏,自2016年发布以来备受好评。然而,在使用游戏时,可能会出现闪退情况,这会影响到玩家的游戏体验。在这篇文章中,我们将为大家详细介绍如何解决“看门狗2闪退”的问题,以及其他看门狗闪退的解决方案。 解决看门狗2闪退方法 1.检查电脑是否符合最低硬件要求 在玩这…

    other 2023年6月26日
    00
  • hive创建表

    Hive创建表 Hive是基于Hadoop的一种数据仓库解决方案,它提供了类SQL的接口,可以将结构化的数据映射为一张数据库表,并通过HiveQL查询语言进行数据的分析和查询。下面我们将介绍如何在Hive中创建表。 创建表语法 我们可以使用CREATE TABLE语句在Hive中创建表格,其语法如下: CREATE [EXTERNAL] TABLE [IF …

    其他 2023年3月28日
    00
合作推广
合作推广
分享本页
返回顶部