[翻译].NET Shell Extensions - Shell Context Menus---.net 外壳扩展之右键菜单

我自己的前言说明:

本文原作者为Dave Kerr,原文链接为.NET Shell Extensions - Shell Context Menus,我是在为了完成最新需求的时候查询资料的时候发现的,因为太久没有看外文资料了,所以为了锻炼一下翻译的,文中有一句未能翻译出来。

引言:

一直到.NET 4.0为止,我们都还是不能通过.NET代码完全实现外壳扩展的功能。但是随着framework的不断提高,现在我们已经可以实现这个功能了。在本文中,我将带领你通过C#类文件快速实现右键菜单扩展功能。

(图中是已经实现的功能,“Count Lines”是我自定义的一个右键选项,文章将仔细解释如何实现该功能)

“.NET外壳扩展”索引:

本文只是“.NET外壳扩展”的一部分,本系列还包括:

  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
  9. .NET Shell Extensions - Deploying SharpShell Servers

什么是Shell Context Menus?

Shell Context Menus是在系统中注册,允许扩展shell对象的Context菜单的COM服务器。这里说的对象可以明确到具体的文件类型,例如“.txt”文件,驱动,文件或者其他的文件类型。这时的Context菜单可以通过Windows管理器快速访问到更多的信息。

准备:

实现外壳扩展功能有很多工作需要完成:我们需要实现具体的COM接口,需要提供服务,并通过各种方式更新注册表。现在我们可以调用我已经写好的一个叫做“SharpShell”库来完成这些复杂的功能,这样我们的任务就变成了只需要创建一个包含已完成延展功能类的轻量级的类库了。

我们的目标:

下面所示代码创建了一个shell扩展,允许你通过右键并选择“Count Lines”来计算出任何文本文件中的行数。另外在文章后半部分我将详细讲解如何创建下面所示的库。我先将代码显示出来的意图是为了强调在调用SharpShell库的情况下如何直截了当的完成库的书写

/// <summary>
/// The CountLinesExtensions is an example shell context menu extension,
/// implemented with SharpShell. It adds the command ‘Count Lines‘ to text
/// files.
/// </summary>
[ComVisible(true)]
[COMServerAssociation(AssociationType.ClassOfExtension, ".txt")]
public class CountLinesExtension : SharpContextMenu
{
    /// <summary>
    /// Determines whether this instance can a shell
    /// context show menu, given the specified selected file list.
    /// </summary>
    /// <returns>
    /// <c>true</c> if this instance should show a shell context
    /// menu for the specified file list; otherwise, <c>false</c>.
    /// </returns>
    protected override bool CanShowMenu()
    {
        //  We always show the menu.
        return true;
    }

    /// <summary>
    /// Creates the context menu. This can be a single menu item or a tree of them.
    /// </summary>
    /// <returns>
    /// The context menu for the shell context menu.
    /// </returns>
    protected override ContextMenuStrip CreateMenu()
    {
        //  Create the menu strip.
        var menu = new ContextMenuStrip();

        //  Create a ‘count lines‘ item.
        var itemCountLines = new ToolStripMenuItem
        {
            Text = "Count Lines...",
            Image = Properties.Resources.CountLines
        };

        //  When we click, we‘ll count the lines.
        itemCountLines.Click += (sender, args) => CountLines();

        //  Add the item to the context menu.
        menu.Items.Add(itemCountLines);

        //  Return the menu.
        return menu;
    }

    /// <summary>
    /// Counts the lines in the selected files.
    /// </summary>
    private void CountLines()
    {
        //  Builder for the output.
        var builder = new StringBuilder();

        //  Go through each file.
        foreach (var filePath in SelectedItemPaths)
        {
            //  Count the lines.
            builder.AppendLine(string.Format("{0} - {1} Lines",
              Path.GetFileName(filePath), File.ReadAllLines(filePath).Length));
        }

        //  Show the ouput.
        MessageBox.Show(builder.ToString());
    }
}

代码可以说简单清晰了,现在就让我们开始仔细研究具体的实现过程吧。

第一步:新建项目

首先,我们需要开始一个新的C#类库项目。

提示:你也可以除了C#,还可以使用VB,在本文中虽然所有的代码都是C#,但是方法原理均同理可得。

在本例中,我们的项目名称是” CountLinesExtension”.

现在我们需要添加一下的引用:

  • System.Windows.Forms
  • System.Drawing

之所以需要System.Windows.Forms,是因为我们需要通过WinForms ContextMenuStrip来定义context菜单。而需要调用System.Drawing的原因在于我们想要用到Icons。

将‘Class1.cs‘重命名为‘CountLinesExtension.cs‘.那么目前我们项目的就变成了这样了:

第二步:引用SharpShell

现在我们需要添加对SharpShell的引用。你可以通过以下这些不同的方法:

添加引用:

在文章最开始的地方下载‘SharpShell Library‘压缩文件,然后直接对SharpShell.dll文件添加引用即可。

提示:文章开始的下载文件是在此文写的时候的文件,如果你想要获得最新的版本,请通过Nuget或者从sharpshell.codeplex.com获取。

Nuget

如果你电脑有Nuget,那么就只需要简单检索SharpShell并安装即可,或者直接访问:https://www.nuget.org/packages/SharpShell

CodePlex

CodePlex 的里面专门的SharpShell主页sharpshell.codeplex.com中你直接可以得到最新的版本。Nuget上虽然也有最新的可靠的版本,但是CodePlex可以还有可用的已写好的betas,而且那上面的文章里面的版本基本都是可用的。

第三步:SharpContextMenu

现在开始就开始真正的研究了,注意了哦。我们的CountLinesExtension继承于SharpContextMenu:

/// <summary>
/// The Count Lines Context Menu Extension
/// </summary>
public class CountLinesExtension : SharpContextMenu
{
}

现在我们既然继承于SharpContextMenu这个父类,那我们就要来实现这个抽象类。右键选择SharpContextMenu,然后选择‘Implement Abstract Class‘:

这个操作将会自动生成SharpContextMenu的两个函数-CanShowMenuCreateMenu

/// <summary>
/// The Count Lines Context Menu Extension
/// </summary>
public class CountLinesExtension : SharpContextMenu
{
    protected override bool CanShowMenu()
    {
        throw new NotImplementedException();
    }

    protected override ContextMenuStrip CreateMenu()
    {
        throw new NotImplementedException();
    }
}

通过实现这两个函数没我们可以实现我们所需的所有功能。两个函数功能具体介绍:

CanShowMenu   (好像有点不对)

这个函数来决定当前的文件是否是我们需要用来显示扩展菜单的文件。被选中的文件类型是SelectedItemPaths的属性。我们可以通过检查来判断当前的文件类型是不是符合要求的文件类型。如果需要显示菜单就返回true,否则就返回false。

CreateMenu

这个函数实现主要的功能。我们需要返回WinForms的ContextMenuStrip

下面是具体的实现:

 protected override bool CanShowMenu()
 {
     //  We will always show the menu.
     return true;
 }
 protected override ContextMenuStrip CreateMenu()
 {
     //  Create the menu strip.
     var menu = new ContextMenuStrip();

    //  Create a ‘count lines‘ item.
     var itemCountLines = new ToolStripMenuItem
    {
         Text = "Count Lines"
     };
     //  When we click, we‘ll call the ‘CountLines‘ function.
     itemCountLines.Click += (sender, args) => CountLines();  

     //  Add the item to the context menu.
     menu.Items.Add(itemCountLines);
     //  Return the menu.
     return menu;
 }   

 private void CountLines()
 {
     //  Builder for the output.
     var builder = new StringBuilder(); 

     //  Go through each file.
     foreach (var filePath in SelectedItemPaths)
     {
         //  Count the lines.
         builder.AppendLine(string.Format("{0} - {1} Lines",Path.GetFileName(filePath),File.ReadAllLines(filePath).Length));
     }

     //  Show the ouput.
     MessageBox.Show(builder.ToString());
 }

对于CanShowMenu,我们常常直接返回true(很快我们就会明白为什么我们不需要验证我们的文本文件了)。对于CreateMenu,我们建立了一个显示菜单,里面只有一个选项,也就是‘Count Lines‘,并实现读出行数的功能。

CountLines这个功能的实现是通过SelectedItemPaths和读取每个文件的函数,然后总结好了显示在弹窗里。

第四步:处理COM注册

现在所剩的事情不多了。首先我们需要添加COMVisible的引用到我们的类里面。

[ComVisible(true)]
public class CountLinesExtension : SharpContextMenu

为什么呢?因为我们的类虽然看起来不像,但是他本质上也是一个COM Server.如果你了解一些基类,那么你可以看我们刚刚实现的COM接口,例如IShellExtInit, IContextMenu, 和 ISharpShellServer。我们不用了解这里到底做了什么,凡是为了保证系统能够创建我们的扩展,她就必须有这个属性。

接下来,我们需要给程序集一个强名称。这里有很多方法实现这个要求,但是总体来说,这是最好的方法。现在我们单机程序右键,然后选择“属性”。再选择“签名”。选中“为程序集签名”,再选择“选择强名称秘钥文件”里面的“新建”,并输入新建的密钥文件名称。你可以自行选择是否需要使用密码保护密钥文件:

最后一步,我们需要关联我们的扩展到具体的文件类型了。这个的实现可以通过对COMServerAssociation(来源于SharpShell)的引用:

 [ComVisible(true)]
 [COMServerAssociation(AssociationType.ClassOfExtension, ".txt")]
 public class CountLinesExtension : SharpContextMenu

在这里我们做了什么呢?我们告诉了SharpShell,注册服务器时,我们想要关联任何与“.txt”相关的类。这就意味着我们不止是仅限于以.TXT结尾的文件,而是任何同类的文件。更权威的说法是,大多是与txt文件共享同样图标的东西。

你可以用COMServerAssociation的属性来实现更多的功能,例如你还可以与文件夹,驱动,位置的文件来实现特定的扩展,等等。另外,关于COM Server Associations的详细的文献资料在SharpShell CodePlex上面。

好了,但目前为止就搞定了!我们已经创建一个可以在作为COM server 在系统中添加自定义菜单的CountLinesExtension程序集项目了。关于注册COM Server和调试部署的任务,我们我们将在下一节,仔细讨论。

调试Shell 扩展

这个Shell扩展功能将被加载到电脑资源管理器时,由于加载.NET COM Server时各种迂回的方式,所以可以说让调试器进入进程并但不执行托管代码几乎可以说是不可能实现的事情。当然,这里还是有一个方法可以快速实现调试。Sharp Shell有一些工具,让实现COM Server变得简单了,其中一个叫做:Server Manager。我们可以用这个工作实现调试。

打开Server Manager工具,然后点击File,选择Load Server,再加载已生成的文件(DLL文件)。你也可以直接拖动文件到主界面中。然后被选中的文件的详细信息就会在旁边显示了。

这个Server Manager非常好用,它可以告诉你服务是否已经安装了和其他各种信息。

如果你要加载SharpContextMenu服务,那就选中‘Tools‘,然后你选中再选中‘Test Context Menu‘。

当你用到了‘Test Context Menu‘的时候,你会得到一份测试窗口。只是Windows资源管理器应用程序的基本实现。你可以通过右键单击来测试。

提示:不管你的COMServerAssocations已经生成了,测试的窗口都会不断的重新创建。

将调试器附加到servermanager过程将允许你调试你的上下文菜单和测试它的功能,而无需在Windows登记服务器。下面是运行Count Line上下文扩展菜单时测试shell的样子

安装和注册Shell扩展

这里又很多方法实现安装和注册Shell扩展。在接下来的这一节里我将仔细介绍这些。

regasm

你可以通过regasm这个工具来实现安装和祖册shell扩展。当使用regasm的时候shell会被装进注册表中(COM服务器的类ID将放在COM服务器类部分,并与实际服务器文件的路径相关联),也会创建关联。

Server Manager

在开发过程中,服务器管理工具是我首选的安装/卸载和注册/注销的方法,因为它可以让安装和注册作为单独的步骤处理。它也将让你指定你是安装/卸载在32位还是64位模式中。

手动注册表操作

Generally a bad approach, but if you absolutely have to then the MSDN documentation for Shell Extensions describes the changes that must be made to the registry to manually register a COM server, or a Managed COM Server(这句不会翻译)。这个文献资料被放在了下一节。

有用的资料

后记

会逐渐通过SharpShell和.NET的使用来时间实现更多的shell扩展功能,形成一个完整的系列。目前那我正在实现图标处理程序(正在编写文档),关于属性表处理程序问题已经实现了(还有些bug正在解决)。

原文地址:https://www.cnblogs.com/Aries-rong/p/8320531.html

时间: 2024-10-16 04:58:41

[翻译].NET Shell Extensions - Shell Context Menus---.net 外壳扩展之右键菜单的相关文章

&lt;转&gt;shell经典,shell十三问

shell 十三问: 1) 为何叫做 shell ? 2) shell prompt(PS1) 与 Carriage Return(CR) 的关系? 3) 别人 echo.你也 echo ,是问 echo 知多少? 4) " "(双引号) 与 ' '(单引号)差在哪? 5) var=value?export 前后差在哪? 6) exec 跟 source 差在哪? 7) ( ) 与 { } 差在哪? 8) $(( )) 与 $( ) 还有${ } 差在哪? 9) [email prot

Shell十三问更新总结版 -- 什么叫做 Shell?-- Shell十三问&lt;第一问&gt;

Shell十三问更新总结版 简介 ChinaUnix 论坛 Shell 版名为網中人的前辈于 2004 年发布的精华贴,最近回炉这块内容,觉得很多东西讲的实在透彻,非常感谢前辈網中人,同时我个人也对这个系列做了一些总结和备注,写于下面章节,虽然这篇文件写于2004年,但是Shell这个东西变化很少,这个系列希望能够帮助到大家提供给大家,有心学习的同学不要读一遍练习一遍就算完了,第一遍和第二遍和第十遍读这个系列,感受绝对不一样,疏漏处请见谅. 網中人原贴:http://bbs.chinaunix.

Linux Shell之一 Shell简介

玩Linux不知道Shell,那就是不懂Linux.这句话足以见证shell在Linux运维中的地位.一直想好好写下shell,但总是不知道如何写起,不是因为Shell太难,而是因为她太庞大,也可能是因为自己shell能力上的不足,怕不能体系化地了解Shell,但是要开始的终究还是要开始,Come On!什么是Shell     Shell是操作系统的最外层,Shell可以合并编程语言以控制进程和文件,以及启动和控制其它程序.shell 通过提示您输入,向操作系统解释该输入,然后处理来自操作系统

Google Chrome插件开发-Context Menus

本节主要介绍如何在Google Chrome浏览器web页面上点击右键弹出自定义菜单,即如何使用谷歌Context Menus API接口.上节已经把主要流程介绍了,这节就直接上代码,代码都是官方例子没有实际意义,但是可以起到抛砖引玉的作用,大家根据自己的需要开发出自己想要的功能才是王道. manifest.json代码如下: { "name": "Context Menus Sample", "description": "Shows

什么是Shell?Shell脚本基础知识详细介绍

这篇文章主要介绍了什么是Shell?Shell脚本基础知识介绍,本文是一篇Shell脚本入门文章,在本文你可学到什么是Shell.有多少种Shell.一个Shell脚本代码实例,需要的朋友可以参考下 Shell本身是一个用C语言编写的程序,它是用户使用Linux的桥梁.Shell既是一种命令语言,又是一种程序设计语言.作为命令语言,它交互式地解释和执行用户输入的命令:作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支. 它虽然不是Linux系统核心

【shell】shell中各种括号的作用()、(())、[]、[[]]、{}

1.(())使用语法: ((表达式))用来扩展Shell中的算术运算,以及赋值运算,扩展for,while,if条件测试运算. 注意点: 1.在双括号结构中,所有的表达式可以像c语言一样,如a++,b-- 2.在双括号结构中,所有变量可以不加入$符号前缀,也可以加入. 3.在双括号可以进行逻辑运算,四则运算,而且运算符合数值之间可以没有空格,也可以有空格. 4.双括号结构扩展了for,while,if条件测试运算. 5.支持多个表达式运算,各个表达式之间用逗号,分开. 6.使用[]时必须保证运算

shell与shell script(2)

Shell 教程 shell 运算符 shell变量 shell字符串 shell传递参数 shell数组 >>返回 06.Shell 运算符 Shell 和其他编程语言一样,支持多种运算符,包括: 算数运算符 关系运算符 布尔运算符 字符串运算符 文件测试运算符 原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用. expr 是一款表达式计算工具,使用它能完成表达式的求值操作. 例如,两个数相加(注意使用的是反引号 ` 而不是单引号 '

Context.js 右键菜单

ContextJS is a lightweight solution for contextual menus. Currently, there are two versions. The first is to be used with Twitters Bootstrap   (bootstrap.css specifically). If you do not use or want to use bootstrap.css, there is a standalone stylesh

qt中qlineedit和qtextedit右键菜单翻译成中文

没有linguist需要安装Linguist: 在Terminal中输入: sudo apt-get install qt4-dev-tools qt4-doc qt4-qtconfig qt4-demos qt4-designer 其中: qt4-dev-tools 中包括了Qt Assistant,Qt Linguist,Qt Creator     qt4-doc 这个是帮助文档     qt4-qtconfig Qt的配置工具,这个装好默认好     qt4-demos 官方的一些Dem