C# 实战 系统图标提取

196 阅读3分钟

前言

在 Windows 系统开发中,有时我们需要获取文件、文件夹或特定文件类型的系统图标。

本文将详细介绍几种在 C# 中提取系统图标的方法。

准备工作

在开始之前,需要引入以下命名空间:

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

方法一:使用 SHGetFileInfo 获取图标

图标提取方法

using System.Runtime.InteropServices;

namespace AppGetIcon
{
    public partial class Form1 : Form
    {

        privateconst uint SHGFI_ICON 
        = 0x000000100;
        privateconst uint SHGFI_SMALLICON 
        = 0x000000000;
        privateconst uint SHGFI_LARGEICON 
        = 0x000000000;

        [DllImport("shell32.dll", CharSet = CharSet.Auto)]
        static extern IntPtr SHGetFileInfo(
        string pszPath,
        uint dwFileAttributes,
        ref SHFILEINFO psfi,
        uint cbSizeFileInfo,
        uint uFlags
        );

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
        struct SHFILEINFO
        {
            public IntPtr hIcon;
            publicint iIcon;
            public uint dwAttributes;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            publicstring szDisplayName;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
            publicstring szTypeName;
        }
        public Form1()
        {
            InitializeComponent();
        }

        public Icon GetFileIcon(string filePath, 
        bool isSmallIcon = true)
        {
            SHFILEINFO shinfo = new SHFILEINFO();
            uint flags = SHGFI_ICON | (isSmallIcon ? 
            SHGFI_SMALLICON : SHGFI_LARGEICON);

            IntPtr hImgSmall = SHGetFileInfo(
                filePath,
                0,
                ref shinfo,
                (uint)Marshal.SizeOf(shinfo),
                flags
            );

            if (shinfo.hIcon == IntPtr.Zero)
                return null;

            return Icon.FromHandle(shinfo.hIcon);
        }

        private void btnGetIcon_Click(object sender, EventArgs e)
        {
            OpenFileDialog dialog = 
            new OpenFileDialog();
            if (dialog.ShowDialog() == DialogResult.OK)
            {
                string filePath = dialog.FileName;
                Icon icon = 
                GetFileIcon(filePath);
                pictureBox1.Image = 
                icon.ToBitmap();
            }
        }
    }
}

命名空间和引用:

using System.Runtime.InteropServices;

这个引用用于支持与Windows API的互操作性。

常量定义:

private const uint SHGFI_ICON = 0x000000100;     
// 获取图标
private const uint SHGFI_SMALLICON = 0x000000000; 
// 小图标
private const uint SHGFI_LARGEICON = 0x000000000; 
// 大图标

Windows API 导入:

[DllImport("shell32.dll", 
CharSet = CharSet.Auto)]
static extern IntPtr SHGetFileInfo(...)

这是导入Windows shell32.dll中的SHGetFileInfo函数,用于获取文件信息包括图标。

SHFILEINFO 结构:

struct SHFILEINFO
{
    public IntPtr hIcon;           
    // 图标句柄
    public int iIcon;              
    // 图标索引
    public uint dwAttributes;      
    // 文件属性
    public string szDisplayName;   
    // 显示名称
    public string szTypeName;      
    // 类型名称
}

这个结构用于存储从Windows API获取的文件信息。

GetFileIcon 方法:

public Icon GetFileIcon(string 
filePath, bool isSmallIcon = true)

这个方法接收文件路径和图标大小选项,返回文件的系统图标。主要步骤包括创建SHFILEINFO结构实例,设置适当的标志(小图标或大图标),调用SHGetFileInfo获取图标句柄,最后将句柄转换为Icon对象。

按钮点击事件处理:

private void btnGetIcon_Click
(object sender, EventArgs e)

当用户点击按钮时,会打开文件选择对话框,获取选中文件的路径,调用GetFileIcon获取图标,并将图标显示在PictureBox控件中。

功能流程:用户点击按钮后打开文件选择对话框,选择文件后获取其图标,然后在界面上显示图标。这个程序的主要用途是允许用户选择一个文件,然后显示该文件类型对应的系统图标。

这对于创建文件浏览器或需要显示文件图标的应用程序很有用。

需要注意的是,代码使用了Windows API,因此这个程序只能在Windows系统上运行。

另外,使用完Icon对象后应该适当释放资源以避免内存泄漏。

总结

通过 SHGetFileInfo 方法,我们可以轻松获取系统图标,无论是特定文件还是文件类型。合理使用这些方法,可以极大地增强应用程序的用户体验。

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

优秀是一种习惯,欢迎大家留言学习!

作者:技术老小子

出处:mp.weixin.qq.com/s/UXrNBTfExQ8ZUGQ164RM2w

声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!