GetSystemIcon.cs

本文介绍了一种从Windows系统中提取文件图标的方法,包括根据文件名或文件类型获取图标,并提供了使用C#实现的具体代码示例。
namespace Helpers
{
    using System;
    using System.Drawing;
    using System.Runtime.InteropServices;
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using Microsoft.Win32;
    using System.Windows.Interop;

    public static class GetSystemIcon
    {
        #region 中间处理过程
        [DllImport("shell32.dll")]
        static extern uint ExtractIconEx(string lpszFile, int nIconIndex, int[] phiconLarge, int[] phiconSmall, uint nIcons);

        static IntPtr ReturnByFileName(string fileName, bool isLarge, int iconIndex = 0)
        {
            var phiconLarge = new int[1];
            var phiconSmall = new int[1];
            ExtractIconEx(fileName, iconIndex, phiconLarge, phiconSmall, 1);
            return new IntPtr(isLarge ? phiconLarge[0] : phiconSmall[0]);
        }

        static dynamic ReturnByFileType(string fileType)
        {
            if (string.IsNullOrEmpty(fileType)) return null;
            string regIconString = null;
            if (fileType[0] == '.')
            {
                //读系统注册表中文件类型信息  
                var regVersion = Registry.ClassesRoot.OpenSubKey(fileType, false);
                if (regVersion != null)
                {
                    var regFileType = regVersion.GetValue("") as string;
                    regVersion.Close();
                    regVersion = Registry.ClassesRoot.OpenSubKey(regFileType + @"\DefaultIcon", false);
                    if (regVersion != null)
                    {
                        regIconString = regVersion.GetValue("") as string;
                        regVersion.Close();
                    }
                }
                if (regIconString == null)
                {
                    //没有读取到文件类型注册信息,指定为未知文件类型的图标
                    regIconString = $@"{Environment.SystemDirectory}\shell32.dll,{0}";
                }
            }
            else
            {
                //直接指定为文件夹图标
                regIconString = $@"{Environment.SystemDirectory}\shell32.dll,{3}";
            }
            var fileIcon = regIconString.Split(',');
            if (fileIcon.Length != 2)
            {
                //系统注册表中注册的标图不能直接提取,则返回可执行文件的通用图标  
                fileIcon = new[] { $@"{Environment.SystemDirectory}\shell32.dll", "2" };
            }
            var shell32Path = fileIcon[0];
            var iconIndex = int.Parse(fileIcon[1]);
            return new { shell32Path, iconIndex };
        }

        #endregion

        /// <summary>
        /// 依据文件名读取图标,若指定文件不存在,则返回空值。  
        /// </summary>
        /// <param name="fileName">文件路径</param>
        /// <param name="isLarge">是否返回大图标</param>
        /// <returns></returns>
        public static Icon GetIconByFileName(string fileName, bool isLarge = true)
        {
            var intPtr = ReturnByFileName(fileName, isLarge);
            return intPtr.ToString() == "0" ? null : Icon.FromHandle(intPtr);
        }

        /// <summary>
        /// 依据文件名读取图像,若指定文件不存在,则返回空值。  
        /// </summary>
        /// <param name="fileName">文件路径</param>
        /// <param name="isLarge">是否返回大图标</param>
        /// <returns></returns>
        public static ImageSource GetImageByFileName(string fileName, bool isLarge = true)
        {
            var intPtr = ReturnByFileName(fileName, isLarge);
            return intPtr.ToString() == "0" ? null : Imaging.CreateBitmapSourceFromHIcon(intPtr, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
        }

        /// <summary>  
        /// 根据文件扩展名(如:.*),返回与之关联的图标。
        /// 若不以"."开头则返回文件夹的图标。  
        /// </summary>  
        /// <param name="fileType">文件扩展名</param>  
        /// <param name="isLarge">是否返回大图标</param>
        /// <returns></returns>  
        public static Icon GetIconByFileType(string fileType, bool isLarge = true)
        {
            Icon resultIcon = null;
            try
            {
                var res = ReturnByFileType(fileType);
                var intPtr = ReturnByFileName(res.shell32Path, isLarge, res.iconIndex);
                resultIcon = Icon.FromHandle(intPtr);
            }
            catch
            {
                // ignored
            }
            return resultIcon;
        }

        /// <summary>  
        /// 根据文件扩展名(如:.*),返回与之关联的图像。
        /// 若不以"."开头则返回文件夹的图标。  
        /// </summary>  
        /// <param name="fileType">文件扩展名</param>  
        /// <param name="isLarge">是否返回大图标</param>
        /// <returns></returns>  
        public static ImageSource GetImageByFileType(string fileType, bool isLarge = true)
        {
            // 处理返回结果
            ImageSource resultIcon = null;
            try
            {
                var res = ReturnByFileType(fileType);
                var intPtr = ReturnByFileName(res.shell32Path, isLarge, res.iconIndex);
                resultIcon = Imaging.CreateBitmapSourceFromHIcon(intPtr, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
            }
            catch
            {
                // ignored
            }
            return resultIcon;
        }

    }

}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值