VS插件编写初探

来源:互联网 发布:淘宝上的港版iphone 编辑:程序博客网 时间:2024/06/13 02:38

图片使用ikaca相册。

 

         本文以一个简单的 VS 插件的编写过程来对 VS 自动化模型进行简单的介绍。这个 VS 插件有以下功能:调用 Google 搜索代码编辑器中选中的文本。

         在代码编辑器中选中文本后单击鼠标右键能弹出如下图所示的菜单:


建立 VS 外接程序的方法非常简单,像普通的 Windows Application 一样, VS 已经提供了完整的向导帮助我们建立 Addin 程序。

通过选择文件菜单、新建、项目打开新建项目对话框,然后选择 其他项目类型 扩展性 ,选择 “Visual Studio 外接程序 打开外接程序向导。

VS2008 为例,打开向导后选择“下一步”出现下图:

选择 C# ,接着根据提示选择支持的 VS 版本:

填写项目名称和说明,出现下面得对话框,

如果想要创建菜单项,可以选中第一项,向导将自动生成相关的代码,建议选中,因为向导所生成的代码可以作为添加更多菜单时代码的模板,而且,所生成的代码支持多种语言。

如果想要外接程序在 VS 启动的时候自动加载,可以选中第二项。如果没有选中此项,可以手动修改工程目录下的 工程名 .AddIn” 文件。该文件其实是 xml 格式的文件,用于配置外接程序的选项,使用记事本或其他文本编辑工具打开,修改此项为 1 即可: <LoadBehavior>0</LoadBehavior>

这样,便生成了一个外接程序的项目,我们可以修改、编写代码完成外接程序。此时的代码已经可以编译运行,运行后,在 VS 的外接程序管理器中将可以插件的有关项。

选中加载插件,便可以在工具菜单中看到名为 “SearchGoogle” 的菜单项。

接下来,我们为插件在代码编辑器中添加右键菜单项,首先,先使用单例模式创建一个类,用于保存生成的右键菜单项对象,大致代码如下:

view plaincopy to clipboardprint?
  1. namespace SearchOnWeb  
  2. {  
  3.   public sealed class InternalInfo  
  4.   {  
  5.     private static InternalInfo internalInfo = null;  
  6.     public static InternalInfo GetInternalInfoInstance()  
  7.     {  
  8.       if (internalInfo == null)  
  9.       {  
  10.         internalInfo = new InternalInfo();  
  11.       }  
  12.       return internalInfo;  
  13.     }  
  14.     private InternalInfo()  
  15.     {  
  16.       this.pop = null;  
  17.     }  
  18.     private CommandBarPopup pop;  
  19.     public CommandBarPopup Pop  
  20.     {  
  21.       get { return pop; }  
  22.       set { pop = value; }  
  23.     }  
  24.   }  
  25. }  

 

创建菜单项的基本步骤如下:

代码应使用 try catch 块,否则,当 VS 加载插件时遇到异常将不再执行后面的代码,导致插件加载失败。

l  创建一个 Command 对象,通过调用 _applicationObject.Commands.AddNamedCommand2 方法实例化 Command 对象。

l  通过 AddControl 方法把命令添加到对应的 CommandBar 中。

l  QueryStatus 方法中添加相应代码,使得菜单可见。(重要,否则看不见菜单

l  Exec 方法中添加相应代码,使菜单执行相应功能。

 

首先,打开 Connect.cs ,在 OnConnection 方法中添加代码。先查找代码编辑器的右键菜单的 CommandBar 对象:

CommandBars commandBars = ((CommandBars)_applicationObject.CommandBars);

CommandBar commandBar = (CommandBar)commandBars["Code Window"];

创建并实例化一个 CommandBarPopup ,设置相应的参数,添加第一级菜单项“ SearchOnWeb ”:

对象创建后,再加入二级菜单“ Google… ”:

要添加多个命令,重复上面的步骤,创建多个 Command 对象并添加到 this.internalInfo.Pop.CommandBar 中。

 

接下来,我们需要在 QueryStatus 方法中添加相应代码,使得菜单可见:

QueryStatus 方法中,我们通过 commandName 判断具体为哪一个菜单, commandName 的命名规则为:

       namespace 名称 .Connect.Command 名称

    如: SearchGoogle.Connect.SearchOnGoogle

 

最后,为菜单添加执行代码, 在调用菜单时, VS 执行 Exec 方法,与 QueryStatus 相同,我们通过 commandName 对菜单项进行判断,菜单被点击后将调用 Exec 函数执行相应的代码。

  1. public void Exec(string commandName, vsCommandExecOption executeOption,  
  2.             ref object varIn, ref object varOut, ref bool handled)  
  3. {  
  4.         handled = false;  
  5.         if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)  
  6.         {  
  7.             if (commandName == "SearchOnWeb.Connect.SearchOnGoogle")  
  8.             {  
  9.                 this.goSearchGoogle();  
  10.                 handled = true;  
  11.                 return;  
  12.             }  
  13.         }  
  14. }  

 

SearchGoogle.Connect.SearchOnGoogle 的具体执行代码将在后文描述。

 

前面我们已经完成了菜单的添加,与 Windows 程序不同,外接程序不是一个独立的程序,也就是说虽然我们退出了 AddIn 程序,但是 VS 可能仍然在运行,这时,我们在 VS 中添加的各种控件、菜单项、窗口等都不会随着我们 AddIn 程序的退出而被卸载,因此,资源回收是 AddIn 必须处理的问题。下面讨论菜单项的卸载。

如果退出了 AddIn ,而菜单没有删除,那么便可能出现这种情况,当我们在此启用 AddIn 时, AddIn 又添加了一个新的一样的菜单项,这样,出现的是两套相同的菜单项,显然不是我们想要的。于是,我们应该在 AddIn 关闭的时候卸载这些菜单。

要完成卸载,我们可以在 OnDisconnection 函数中实现,卸载菜单很容易,只需获得 Command 对象调用 Delete 方法便可,下面代码将所添加的两个菜单项删除:

插件卸载后的菜单如下:

这样,一个简单的插件的框架就完成了,我们最后为 goSearchGoogle 添加代码:

private void goSearchGoogle()

{

                   TextSelection selection = (TextSelection)_applicationObject.ActiveDocument.Selection;

                   if (selection == null || selection.Text == "")

                   {

                            System.Windows.Forms.MessageBox.Show(" 没有选中的文本 .");

                                     return;

                   }

                   _applicationObject.ItemOperations.Navigate("http://www.google.cn/search?hl=zh-CN&q=" + selection.Text, vsNavigateOptions.vsNavigateOptionsNewWindow);

}

 

上面代码通过 TextSelection 对象获得代码编辑器当前文档中选中的文本,调用 Navigate 方法访问 Google