Windows操作系统的文件图标是根据文件的类型,或者说文件扩展名读取的。下面是一个采用此方法读取指定类型文件图标和类型描述信息的示例。
介绍下实现方法:
例如一个.txt扩展名的文件图标,通过注册表项HKCR/.txt找到该类型为txtfile
再通过HKCR/txtfile得到它的描述信息是“文本文档”(你的操作系统也可能会显示为“Text Document”,或者其他的描述信息)
通过HKCR/txtfile/DefaultIcon得到该类型的缺省图标的文件和图标索引信息(注意,你的操作系统也许与截图中的值内容不同)
然后我们利用系统API函数ExtractIconExW将图标提取出来就可以了。
然而可执行文件exefile类型的图标(通常扩展名为.exe)会取自自身的文件中的第一个图标,因为我们按扩展名取图标,并没有可执行文件本身的路径,那么用一个默认的共同exe图标代替,这里假设为系统目录shell32.dll文件中索引号为2的图标。
摘取代码如下:
/// <summary>
/// 通过扩展名得到图标和描述
/// </summary>
/// <param name="ext">扩展名(如“.txt”)</param>
/// <param name="largeIcon">得到大图标</param>
/// <param name="smallIcon">得到小图标</param>
/// <param name="description">得到类型描述或者空字符串</param>
void GetExtsIconAndDescription(string ext, out Icon largeIcon, out Icon smallIcon, out string description)
{
GetDefaultIcon(out largeIcon, out smallIcon); //得到缺省图标
description = ""; //缺省类型描述
RegistryKey extsubkey = Registry.ClassesRoot.OpenSubKey(ext); //从注册表中读取扩展名相应的子键
if (extsubkey == null) return;
string extdefaultvalue = extsubkey.GetValue(null) as string; //取出扩展名对应的文件类型名称
if (extdefaultvalue == null) return;
if (extdefaultvalue.Equals("exefile", StringComparison.OrdinalIgnoreCase)) //扩展名类型是可执行文件
{
RegistryKey exefilesubkey = Registry.ClassesRoot.OpenSubKey(extdefaultvalue); //从注册表中读取文件类型名称的相应子键
if (exefilesubkey != null)
{
string exefiledescription = exefilesubkey.GetValue(null) as string; //得到exefile描述字符串
if (exefiledescription != null) description = exefiledescription;
}
System.IntPtr exefilePhiconLarge = new IntPtr();
System.IntPtr exefilePhiconSmall = new IntPtr();
NativeMethods.ExtractIconExW(Path.Combine(Environment.SystemDirectory, "shell32.dll"), 2, ref exefilePhiconLarge, ref exefilePhiconSmall, 1);
if (exefilePhiconLarge.ToInt32() > 0) largeIcon = Icon.FromHandle(exefilePhiconLarge);
if (exefilePhiconSmall.ToInt32() > 0) smallIcon = Icon.FromHandle(exefilePhiconSmall);
return;
}
RegistryKey typesubkey = Registry.ClassesRoot.OpenSubKey(extdefaultvalue); //从注册表中读取文件类型名称的相应子键
if (typesubkey == null) return;
string typedescription = typesubkey.GetValue(null) as string; //得到类型描述字符串
if (typedescription != null) description = typedescription;
RegistryKey defaulticonsubkey = typesubkey.OpenSubKey("DefaultIcon"); //取默认图标子键
if (defaulticonsubkey == null) return;
//得到图标来源字符串
string defaulticon = defaulticonsubkey.GetValue(null) as string; //取出默认图标来源字符串
if (defaulticon == null) return;
string[] iconstringArray = defaulticon.Split(',');
int nIconIndex = 0; //声明并初始化图标索引
if (iconstringArray.Length > 1)
if (!int.TryParse(iconstringArray[1], out nIconIndex))
nIconIndex = 0; //int.TryParse转换失败,返回0
//得到图标
System.IntPtr phiconLarge = new IntPtr();
System.IntPtr phiconSmall = new IntPtr();
NativeMethods.ExtractIconExW(iconstringArray[0].Trim('"'), nIconIndex, ref phiconLarge, ref phiconSmall, 1);
if (phiconLarge.ToInt32() > 0) largeIcon = Icon.FromHandle(phiconLarge);
if (phiconSmall.ToInt32() > 0) smallIcon = Icon.FromHandle(phiconSmall);
}
/// <summary>
/// 获取缺省图标
/// </summary>
/// <param name="largeIcon"></param>
/// <param name="smallIcon"></param>
private static void GetDefaultIcon(out Icon largeIcon, out Icon smallIcon)
{
largeIcon = smallIcon = null;
System.IntPtr phiconLarge = new IntPtr();
System.IntPtr phiconSmall = new IntPtr();
NativeMethods.ExtractIconExW(Path.Combine(Environment.SystemDirectory, "shell32.dll"), 0, ref phiconLarge, ref phiconSmall, 1);
if (phiconLarge.ToInt32() > 0) largeIcon = Icon.FromHandle(phiconLarge);
if (phiconSmall.ToInt32() > 0) smallIcon = Icon.FromHandle(phiconSmall);
}