.NET Shell Extensions - Shell Icon Handlers (图标处理程序)
使用 .NET 快速创建 Shell 图标处理程序扩展
引言
Shell 图标处理程序是注册在系统中的 DLL,用于自定义图标的外观。在本文中,我将向您展示如何使用 .NET 和一个名为 SharpShell
的库创建图标处理程序扩展。
系列文章
本文是 '.NET Shell Extensions' 系列的一部分,该系列包括
- .NET Shell Extensions - Shell Context Menus (右键菜单扩展)
- .NET Shell Extensions - Shell Icon Handlers (图标处理程序)
- .NET Shell Extensions - Shell Info Tip Handlers (信息提示处理程序)
- .NET Shell Extensions - Shell Drop Handlers (拖放处理程序)
- .NET Shell Extensions - Shell Preview Handlers (预览处理程序)
- .NET Shell Extensions - Shell Icon Overlay Handlers (图标叠加处理程序)
- .NET Shell Extensions - Shell Thumbnail Handlers (缩略图处理程序)
- .NET Shell Extensions - Shell Property Sheets (属性表处理程序)
我们的目标
为了展示 SharpShell
和 Shell 图标处理程序的工作原理,我们将创建一个 DLL,该 DLL 更改 *.dll 文件的图标——将标准 DLL 显示为一种颜色,将程序集显示为另一种颜色。为了展示使用 SharpShell 完成此操作的简便性,这是最终的类
/// <summary>
/// The DllIconHandler is a Shell Icon Handler exception that
/// shows different icons for native and managed dlls.
/// </summary>
[ComVisible(true)]
[COMServerAssocation(AssociationType.ClassOfExtension, ".dll")]
public class DllIconHandler : SharpIconHandler
{
/// <summary>
/// Gets the icon
/// </summary>
/// <param name="smallIcon">if set to <c>true</c> provide a small icon.</param>
/// <param name="iconSize">Size of the icon</param>
/// <returns>
/// The icon for the file
/// </returns>
protected override Icon GetIcon(bool smallIcon, uint iconSize)
{
// The icon we'll return
Icon icon = null;
// Check the assembly name. If it's a native dll, this'll throw an exception.
try
{
// SelectedItemPath is provided by 'SharpIconHandlder'
// and contains the path of the file.
AssemblyName.GetAssemblyName(SelectedItemPath);
}
catch (BadImageFormatException)
{
// The file is not an assembly.
icon = Properties.Resources.NativeDll;
}
catch (Exception)
{
// Some other eception occurred, so assume we're native.
icon = Properties.Resources.NativeDll;
}
// If we haven't determined that the DLL is native, use the managed icon.
if (icon == null)
icon = Properties.Resources.ManagedDll;
// Return the icon with the correct size.
// Use the SharpIconHandler 'GetIconSpecificSize'
// function to extract the icon of the required size.
return GetIconSpecificSize(icon, new Size((int)iconSize, (int)iconSize));
}
}
不可能再简单了。现在我们将详细介绍如何创建图标处理程序扩展。
步骤 1:创建项目
首先,创建一个新的 C# 类库项目。
提示:您可以使用 Visual Basic 而不是 C# - 在本文中,源代码是 C#,但创建 Visual Basic Shell Extension 的方法是一样的。
在此示例中,我们将项目命名为“DllIconHandler
”。将“Class1.cs”文件重命名为“DllIconHandler.cs”。
现在添加以下引用
System.Windows.Forms
System.Drawing
需要 System.Windows.Forms
,因为 SharpShell
库依赖于它(例如用于上下文菜单)。需要 System.Drawing
,因为我们将要使用图标。
提示:如果您使用 Nuget 安装
SharpShell
(请参见“步骤 2”),则无需添加这些引用 - 它们将自动添加。
步骤 2:引用 SharpShell
现在我们需要添加对核心 SharpShell
库的引用。你可以通过几种不同的方式做到这一点:
添加引用
下载文章顶部的“SharpShell
库”zip 文件,并添加对下载的 SharpShell.dll 文件的引用。
提示:文章中的下载在撰写本文时是正确的——如果您需要最新版本,请使用 Nuget(如下所述)或从 sharpshell.codeplex.com 获取库。
使用 Nuget
如果您安装了 Nuget,只需快速搜索 SharpShell 并直接安装它 - 或在 https://nuget.net.cn/packages/SharpShell 获取包详细信息。
使用 CodePlex
与其从本页面获取库(可能不是最新版本),您还可以始终从 CodePlex - SharpShell 主页获取最新版本的库,网址为 sharpshell.codeplex.com。Nuget 始终拥有最新稳定版本 - CodePlex 可能提供 Beta 版本,而 CSDN 文章将包含撰写本文时可用的版本。
步骤 3:从 SharpIconHandler 派生
现在我们将实际为 DLL 图标处理程序创建功能。使您的 DllIconHandler
类从 SharpIconHandler
派生
/// <summary>
/// The DllIconHandler is a Shell Icon Handler exception that
/// shows different icons for native and managed DLLs.
/// </summary>
public class DllIconHandler : SharpIconHandler
{
}
现在我们必须实现类的抽象成员。右键单击该行上的 SharpIconHandler
部分,然后选择“实现抽象类”。
这将创建用于获取图标的函数的实现——这是必需的,即 GetIcon
。
/// <summary>
/// Gets the icon.
/// </summary>
/// <param name="smallIcon">if set to <c>true</c> provide a small icon.</param>
/// <param name="iconSize">Size of the icon.</param>
/// <returns>
/// The icon for the file.
/// </returns>
protected override Icon GetIcon(bool smallIcon, uint iconSize)
{
// The icon we'll return
Icon icon = null;
// Check the assembly name. If it's a native DLL, this'll throw an exception.
try
{
// SelectedItemPath is provided by 'SharpIconHandlder'
// and contains the path of the file.
AssemblyName.GetAssemblyName(SelectedItemPath);
}
catch (BadImageFormatException)
{
// The file is not an assembly.
icon = Properties.Resources.NativeDll;
}
catch (Exception)
{
// Some other eception occurred, so assume we're native.
icon = Properties.Resources.NativeDll;
}
// If we haven't determined that the DLL is native, use the managed icon.
if (icon == null)
icon = Properties.Resources.ManagedDll;
// Return the icon with the correct size. Use the SharpIconHandler 'GetIconSpecificSize'
// function to extract the icon of the required size.
return GetIconSpecificSize(icon, new Size((int)iconSize, (int)iconSize));
}
调用 GetIcon
以获取所选文件(或文件夹、驱动器等)的 Icon
对象。所选文件(或文件夹、驱动器等)的路径存储在 SelectedItemPath
属性中。
如果 shell 明确要求小图标,则将 smallIcon
设置为 true
。通常,我们可以忽略此项,因为还会提供所需的图标大小,即 iconSize
。
基类中有一个名为 GetIconSpecificSize
的帮助函数,它将从 Icon
对象返回正确大小的图标——如果未使用此函数,系统将获取第一个图标并自行调整大小,这通常不是您想要的。
步骤 4:处理 COM 注册
只剩下几件事要做。首先,我们必须为类添加 COMVisible
属性。
[ComVisible(true)]
public class DllIconHandler : SharpIconHandler
这是因为尽管 SharpShell
隐藏了大部分 COM 管道,但实际的 COM 服务器是这个类本身——所以它必须是 COM 可见的。
接下来,我们必须为程序集提供强名称。对此要求有解决办法,但通常这是最好的方法。为此,请右键单击项目,然后选择“属性”。然后转到“签名”。选择“为程序集签名”,为密钥指定“新建”并选择一个密钥名称。如果需要,可以为密钥设置密码,但这不是必需的
最后一步——我们现在需要将我们的扩展与某些文件类型关联起来。我们可以使用 COMServerAssociation
属性来做到这一点
[ComVisible(true)]
[COMServerAssocation(AssociationType.ClassOfExtension, ".dll")]
public class DllIconHandler : SharpIconHandler
那么我们在这里做了什么?我们已经告诉 SharpShell
,在注册服务器时,我们希望将其与 *.dll 文件的 class
相关联。这意味着它不仅适用于所有以 *.dll 结尾的文件,还适用于所有属于同一类的文件。简单来说,这就是大多数与 *.dll 文件共享相同图标的东西。
您可以与文件、文件夹、类、驱动器等相关联——有关使用关联属性的完整文档可在 CodePlex 网站上找到,网址为 COM Server Associations。
就这样!构建项目将创建 DllIconHandler
程序集,该程序集可以注册为 COM 服务器以添加图标处理程序系统,为 DLL 文件提供彩色图标。
调试 Shell Extension
如果您看过文章 .NET Shell Extensions - Shell Context Menus,您可能会认出“服务器管理器”工具。这是 SharpShell
源代码中的一个工具,可用于帮助调试 Shell 扩展。
提示:如果你想要最新版本的工具,它们可以从 CodePlex 网站预先构建好。
打开服务器管理器工具,然后使用文件 > 加载服务器来加载 DllIconHandler.dll 文件。您也可以将服务器拖到主窗口中。选择服务器将显示有关它的详细信息。选择服务器。
现在按“测试服务器”或使用“服务器 > 测试...”。这将打开测试 Shell,它将模拟将调用服务器的调用,就像 Windows Shell 在进行调用一样——但是,由于这是一个托管应用程序,您可以快速附加调试器来查看您的服务器是如何运行的。它还允许您在无需安装或注册服务器的情况下对其进行测试,这将为您节省大量时间(在实际 Explorer 中测试时,您将不得不经常重启它来解锁文件以便更新它)。
测试 Shell 图标处理程序扩展时,请注意以下几点
- 只有与服务器上指定的 COM 服务器关联匹配的 Shell 项才会被测试
- 只有右侧的列表视图会测试图标——左侧的文件夹视图将使用标准的 Shell 图标
安装和注册 Shell Extension
您可以查看 ".NET Shell Extensions - Shell Context Menus" 一文中的“安装和注册 Shell 扩展”部分,了解如何安装和注册这些扩展——过程相同。
有用资源
如何创建图标处理程序:MSDN 关于 Shell 图标处理程序的资源中心。请注意,这些资源都是针对 C 和 C++ 的。
SharpShell on CodePlex:SharpShell 项目的主页 - 包括文档、讨论以及最新的源代码和发行版。
下一步?
SharpShell 将随着时间的推移提供一种使用 .NET 创建所有可用 Shell 扩展的机制。到目前为止,完全支持的是上下文菜单扩展、图标处理程序和信息提示处理程序——关注 CodePlex 项目以获取最新信息,因为会添加新功能。
历史
- 2015 年 1 月 19 日:初始版本