4

名为SharpShell的 .NET Shell 扩展框架非常棒;我开发了一个右键单击文件 Shell ContextMenu “非常容易”,可以同时选择文件和目录。

现在我想通过右键单击空白空间(即在桌面上或我在文件夹内的白点上)来开发一个 Shell ContextMenu。仍然可以使用 SharpShell 吗?还是我需要转向不同的解决方案?...在​​第二种情况下...您有什么建议?

谢谢

4

2 回答 2

6

下面介绍的两种解决方案都有效,但与此同时,我发现有一个更简单的解决方案实际上已经在 SharpShell 附带的示例中使用。

将该CopyDirectoryLocationHandler类视为为目录背景(和桌面)注册的上下文菜单处理程序的示例:

[ComVisible(true)]
[COMServerAssociation(AssociationType.Class, @"Directory\Background")]
public class CopyDirectoryLocationHandler : SharpContextMenu
{
   // ...
}

如果您希望处理程序仅处理桌面背景上的点击,请改用以下代码:

[ComVisible(true)]
[COMServerAssociation(AssociationType.Class, @"DesktopBackground")]
public class CopyDirectoryLocationHandler : SharpContextMenu
{
   // ...
}

旧的过时答案:

您可以毫无问题地为此目的使用 SharpShell。有两种可能的方法:

  1. 注册Shell Extension,自己处理文件夹背景

或者

  1. 修改 SharpShell 为您处理文件夹背景扩展名的注册。

注册Shell Extension,自己处理文件夹背景

您的 shell 扩展是一个 COM 服务器,因此通过 GUID 被系统识别。然后在注册表中的位置使用此 GUID 为不同目的注册 COM 扩展。当我们为了扩展文件夹背景的上下文菜单等目的而手动注册扩展时,最好我们的扩展具有固定的 GUID。

目前您的课程如下所示:

 [ComVisible(true)]
 [COMServerAssociation(AssociationType.Directory)]
 public class MyContextMenuExtension : SharpContextMenu
 {

编译时,编译器会自动生成一个用于该类的 GUID。但是我们可以像这样指定一个特定的使用:

 [Guid("A75AFD0D-4A63-41E3-AAAA-AD08A574B8B0")]
 [ComVisible(true)]
 [COMServerAssociation(AssociationType.Directory)]
 public class MyContextMenuExtension : SharpContextMenu
 {

不要使用与此处所示相同的 GUID,而是通过菜单工具 > 创建 GUID 在 Visual Studio 中创建自己的唯一 GUID。为您编写的每个 shell 扩展使用不同的 GUID。

然后重新编译 dll 并再次安装和注册(使用 regasm 或 SharpShell 服务器管理器工具。

然后使用以下内容创建一个名为“registry.reg”的文本文件(使用您自己的特定 GUID)。而不是“MyContextMenuExtension”指定您的扩展名。

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Directory\Background\shellex\ContextMenuHandlers\MyContextMenuExtension]
@="{A75AFD0D-4A63-41E3-AAAA-AD08A574B8B0}"

双击安装“registry.reg”文件。当您打开文件夹背景或桌面的上下文菜单时,您的扩展现在应该处于活动状态。

除了使用 *.reg 文件,您还可以使用注册表编辑器手动进行更改,或者如果您有安装程序,请指示安装程序进行这些注册表更改。


修改 SharpShell 为您处理文件夹背景扩展名的注册

对 SharpShell 源代码进行以下更改:

在文件AssociationType.cs中为枚举添加一个新的枚举值AssociationType

  /// <summary>
  /// Create an association to the unknown files class.
  /// </summary>
  UnknownFiles,

  /// <summary>
  /// Create an association to the background of folders and the desktop
  /// </summary>
  DirectoryBackground

在文件中ServerRegistrationManager.cs添加一个新的私有字符串常量:

/// <summary>
/// The 'directory' special class.
/// </summary>
private const string SpecialClass_Directory = @"Directory";

 /// <summary>
/// The 'directory background' special class.
/// </summary>
private const string SpecialClass_DirectoryBackground = @"Directory\Background";

同样在大 switch 语句ServerRegistrationManager.cs的方法中的文件中添加一个新的案例,如下所示:CreateClassNamesForAssociations

          case AssociationType.Directory:

               //  Return the directory class.
               return new[] { SpecialClass_Directory };

          case AssociationType.DirectoryBackground:

               //  Return the directory background class.
               return new[] { SpecialClass_DirectoryBackground };

最后你只需要告诉你自己的扩展类使用这个新的枚举值:

 [Guid("A75AFD0D-4A63-41E3-AAAA-AD08A574B8B0")]
 [ComVisible(true)]
 [COMServerAssociation(AssociationType.Directory)]
 [COMServerAssociation(AssociationType.DirectoryBackground)]
 public class MyContextMenuExtension : SharpContextMenu
 {
于 2016-06-03T19:25:21.437 回答
1

SharpShell前段时间用过,从那以后就忘记了(因为它完美无缺)。我在文件和文件夹上使用过它,所以你的问题引起了我的兴趣。对该工具的一些研究使我得到了答案(不幸的是)

绑定是通过 SharpShell 上的 com 服务器关联完成的。通过查看 com 服务器关联的文档,我没有看到实现所需功能的方法。

PS:我鼓励您在文档页面上发表评论,或直接与库的作者联系。他似乎真的很有帮助(我之前联系过他)。

于 2016-06-03T13:11:28.327 回答