.NET Shell Extensions - Shell Icon Overlay Handlers (图标叠加处理程序)
使用 .NET 创建 Shell 图标覆盖处理程序!
引言
Shell 图标覆盖处理程序可以非常有用。它们允许您在 Shell 对象上显示一个图标覆盖,以提供额外的信息。像 Dropbox 这样的程序就使用这些覆盖来显示图标是否已同步。在本文中,我将向您展示如何使用 SharpShell 轻松创建 Shell 图标覆盖处理程序!
下面是我们创建的示例的屏幕截图 - 它在只读文件上显示一个锁形图标。
上图:文件夹中的一些文本文件。安装此 Shell 图标扩展后,只读文件将带有锁形覆盖图标。
系列文章
本文是 '.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 (属性表处理程序)
入门
Shell 扩展通常用 C 或 C++ 编写。在 .NET Framework 4 发布之前,无法使用 .NET 可靠地创建 Shell 扩展。现在您可以了。使用 SharpShell
库,所有 COM 样板代码都已为您处理,您只需创建一个扩展类,用一些属性对其进行装饰,并重写一些函数。
为了展示这有多么容易,让我们看看只读文件图标覆盖处理程序的完整代码。
我们的目标
这是只读覆盖处理程序的完整代码。它非常精简——现在我们已经完整地看到了它,我将逐步介绍如何创建自己的扩展。
/// <summary>
/// The ReadOnlyFileIconOverlayHandler is an IconOverlayHandler that shows
/// a padlock icon over files that are read only.
/// </summary>
[ComVisible(true)]
public class ReadOnlyFileIconOverlayHandler : SharpIconOverlayHandler
{
/// <summary>
/// Called by the system to get the priority, which is used to determine
/// which icon overlay to use if there are multiple handlers. The priority
/// must be between 0 and 100, where 0 is the highest priority.
/// </summary>
/// <returns>
/// A value between 0 and 100, where 0 is the highest priority.
/// </returns>
protected override int GetPriority()
{
// The read only icon overlay is very low priority
return 90;
}
/// <summary>
/// Determines whether an overlay should be shown for the shell item
/// with the path 'path' and
/// the shell attributes 'attributes'
/// </summary>
/// <param name="path">The path for the shell item. This is not necessarily the path
/// to a physical file or folder.</param>
/// <param name="attributes">The attributes of the shell item.</param>
/// <returns>
/// <c>true</c> if this an overlay should be shown for the specified item;
/// otherwise, <c>false</c>.
/// </returns>
protected override bool CanShowOverlay(string path, FILE_ATTRIBUTE attributes)
{
try
{
// Get the file attributes
var fileAttributes = new FileInfo(path);
// Return true if the file is read only, meaning we'll show the overlay
return fileAttributes.IsReadOnly;
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// Called to get the icon to show as the overlay icon
/// </summary>
/// <returns>
/// The overlay icon
/// </returns>
protected override System.Drawing.Icon GetOverlayIcon()
{
// Return the read only icon
return Properties.Resources.ReadOnly;
}
}
这大部分是注释——所以您可以看到,使用 SharpShell 创建覆盖处理程序非常简单!
步骤 1:创建项目
首先,创建一个新的 C# 类库项目。
提示:您可以使用 Visual Basic 而不是 C# - 在本文中,源代码是 C#,但创建 Visual Basic Shell Extension 的方法是一样的。
在此示例中,我们将项目命名为 'ReadOnlyFileIconOverlayHandler
'。
提示:如果您通过 Nuget 添加 SharpShell 的引用,下方的引用将自动添加。
现在添加以下引用
System.Windows.Forms
System.Drawing
将 'Class1.cs' 文件重命名为 'ReadOnlyFileIconOverlayHandler.cs'。
步骤 2:引用 SharpShell
现在我们需要添加对核心 SharpShell
库的引用。你可以通过几种不同的方式做到这一点:
添加引用
下载文章顶部的 'SharpShell Library' zip 文件,并添加对下载的 SharpShell.dll 文件的引用。
提示:本文的下载在撰写时是正确的——如果您需要最新版本,请使用 Nuget(如下所述)或从 sharpshell.codeplex.com 获取库。
使用 Nuget
如果您安装了 Nuget,只需快速搜索 SharpShell 并直接安装它 - 或在 https://nuget.net.cn/packages/SharpShell 获取包详细信息。
使用 CodePlex
与其从本页面获取库(可能不是最新版本),您还可以随时从 CodePlex 获取最新版本的库——在 SharpShell 主页上,网址是 sharpshell.codeplex.com。Nuget 始终拥有最新稳定版本——CodePlex 可能有测试版,而 CodeProject 文章将拥有撰写时可用的版本。
步骤 3:继承自 SharpIconOverlayHandler
现在事情变得有趣了。让您的 ReadOnlyFileIconOverlayHandler
类继承自 SharpIconOverlayHandler
/// <summary>
/// The ReadOnlyFileIconOverlayHandler is an IconOverlayHandler that shows
/// a padlock icon over files that are read only.
/// </summary>
public class ReadOnlyFileIconOverlayHandler : SharpIconOverlayHandler
现在我们必须实现该类的抽象成员。右键单击该行的 SharpIconOverlayHandler
部分,然后选择 '实现抽象类'。这将创建我们必须提供的函数的空实现。
/// <summary>
/// The ReadOnlyFileIconOverlayHandler is an IconOverlayHandler that shows
/// a padlock icon over files that are read only.
/// </summary>
public class ReadOnlyFileIconOverlayHandler : SharpIconOverlayHandler
{
protected override int GetPriority()
{
throw new NotImplementedException();
}
protected override bool CanShowOverlay(string path, FILE_ATTRIBUTE attributes)
{
throw new NotImplementedException();
}
protected override System.Drawing.Icon GetOverlayIcon()
{
throw new NotImplementedException();
}
}
下面是对这些函数的描述以及如何使用它们
GetPriority
此函数必须返回处理程序的优先级。当一个文件有两个图标覆盖时,将使用优先级最高者。为了混淆视听,最高优先级是 0——最低优先级是 100。
CanShowOverlay
每次显示 Shell 项时,都会调用此函数。Shell 项的路径在 path 参数中提供。还提供了 FILE_ATTRIBUTE
标志(例如 FILE_ATTRIBUTE_DIRECTORY
这样的属性)。如果要为指定的*.文件显示图标覆盖,请返回 true
。
GetOverlayIcon
此函数必须返回一个标准的 .NET System.Drawing.Icon
对象,该对象是要使用的覆盖图标。
步骤 3:实现函数
我们对这些函数的实现将如下所示。首先,GetPriority
protected override int GetPriority()
{
// The read only icon overlay is very low priority.
return 90;
}
此覆盖是有用的,但不如 TortoiseSVN 的状态图标等重要,因此我们将其优先级设置得较低。
现在,CanShowOverlay
protected override bool CanShowOverlay(string path, FILE_ATTRIBUTE attributes)
{
try
{
// Get the file attributes
var fileAttributes = new FileInfo(path);
// Return true if the file is read only, meaning we'll show the overlay
return fileAttributes.IsReadOnly;
}
catch (Exception)
{
return false;
}
}
我们只在能够获取文件属性而不引发异常,并且这些属性指示只读时返回 true
(显示覆盖)。(为什么我不使用 FILE_ATTRIBUTE_READONLY
?嗯,显然它对目录不起作用。)
最后一个函数,GetOverlayIcon
protected override System.Drawing.Icon GetOverlayIcon()
{
// Return the read only icon
return Properties.Resources.ReadOnly;
}
在项目中,我向资源添加了一个名为 'ReadOnly
' 的图标——它只是返回该图标。
步骤 4:处理 COM 注册
只剩下几件事情要做。首先,我们必须向类添加 COMVisible
属性。
[ComVisible(true)]
public class ReadOnlyFileIconOverlayHandler : SharpIconOverlayHandler
接下来,我们必须为程序集指定一个强名称。有办法绕过此要求,但通常这是最佳方法。为此,右键单击项目并选择 '属性'。然后转到 '签名'。选择 '签名程序集',为密钥指定 '新建',然后选择一个密钥名称。您可以为密钥设置密码,但这并非必需。
调试 Shell Extension
Shell 扩展将托管在 Windows 资源管理器中——由于 .NET COM 服务器加载方式的曲折性,几乎不可能将调试器附加到进程中并逐步调试托管代码。但是,有一种方法可以快速调试您的扩展。SharpShell 附带了一些工具,可以更轻松地处理 SharpShell COM 服务器,其中之一是服务器管理器。我们可以使用此工具调试我们的扩展。打开服务器管理器,然后加载扩展。选择 '安装',然后选择 '注册',现在打开测试 Shell 并选择 'Shell 打开对话框'——现在当您在文件系统中移动时,您的扩展中的断点应该会被命中。
安装和注册 Shell Extension
有几种方法可以安装和注册 SharpShell Shell 扩展。在本节中,我将详细介绍所有这些方法。
regasm 工具
您可以使用 'regasm' 工具安装和注册 Shell 扩展。在使用 regasm 时,Shell 扩展将安装到注册表中(即,COM 服务器的类 ID 将放入 COM 服务器类部分,并与实际服务器文件的路径关联),它还将注册关联。
服务器管理器工具
服务器管理器工具是我安装/卸载和注册/注销的首选方法,至少在开发过程中,因为它允许您将安装和注册作为单独的步骤。它还可以让您指定是在 32 位还是 64 位模式下安装/卸载等。
手动注册表操作
通常是一种糟糕的方法,但如果绝对有必要,那么 MSDN 文档中描述了手动注册 COM 服务器或托管 COM 服务器必须对注册表进行的更改。文档列在“有用资源”部分。
备忘单
以下是一些使用 SharpShell 和图标覆盖处理程序的有用技巧。
- 您的覆盖似乎不起作用?打开 regedit 并检查路径
HKLM\Software\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayHandlers
Windows 只支持有限数量的处理程序——按字母顺序排列。可能安装了太多。 - 如果您需要记录事件,请以管理员身份运行服务器管理器,然后选择 '诊断 > 启用 SharpShell 日志'。您现在可以使用函数
Log
LogError
LogWarning
在您的服务器类中,这些消息将被写入 Windows 事件日志(在“应用程序”下)。
历史
- 2013 年 9 月 14 日:初始版本