65.9K
CodeProject 正在变化。 阅读更多。
Home

.NET Shell Extensions - Shell Icon Handlers (图标处理程序)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.91/5 (28投票s)

2013年1月9日

CPOL

7分钟阅读

viewsIcon

100166

downloadIcon

3578

使用 .NET 快速创建 Shell 图标处理程序扩展

引言

Shell 图标处理程序是注册在系统中的 DLL,用于自定义图标的外观。在本文中,我将向您展示如何使用 .NET 和一个名为 SharpShell 的库创建图标处理程序扩展。

上图:一个正在运行的图标处理程序扩展示例。此扩展将 DLL 文件的图标更改为指示它们是程序集还是本机 DLL。

系列文章

本文是 '.NET Shell Extensions' 系列的一部分,该系列包括

  1. .NET Shell Extensions - Shell Context Menus (右键菜单扩展)
  2. .NET Shell Extensions - Shell Icon Handlers (图标处理程序)
  3. .NET Shell Extensions - Shell Info Tip Handlers (信息提示处理程序)
  4. .NET Shell Extensions - Shell Drop Handlers (拖放处理程序)
  5. .NET Shell Extensions - Shell Preview Handlers (预览处理程序)
  6. .NET Shell Extensions - Shell Icon Overlay Handlers (图标叠加处理程序)
  7. .NET Shell Extensions - Shell Thumbnail Handlers (缩略图处理程序)
  8. .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”。

现在添加以下引用

  1. System.Windows.Forms
  2. 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 图标处理程序扩展时,请注意以下几点

  1. 只有与服务器上指定的 COM 服务器关联匹配的 Shell 项才会被测试
  2. 只有右侧的列表视图会测试图标——左侧的文件夹视图将使用标准的 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 日:初始版本
© . All rights reserved.