VS2013在右键菜单添加命令插件开发
一、选择Visual Studio Package模板建立插件项目
由于此功能需要在右键菜单上添加命令,所以选择Visual Studio Package模板,根据模板向导步骤插件项目,在Select VSPackage Options步骤的时候选择Menu Command选项,如图-1所示:

图-1
接下来是设置命令的名称,如图-2所示
 图-2
图-2
修改Command name的值,将其设置为我们要添加到右键菜单时的名称。Command ID可选择是否修改,值是一个十六进制数,由于标识我们的添加的命令。按照模板向导建立好插件项目后,按F5运行插件项目,此时VS会新建一个实验实例,点击工具菜单,可以看到已经有一个命令添加到工具菜单里了,如名称My Command name(如果没有修改Command name的值得话)如图-3所示:
 图-3
图-3
点击该命令的时候会弹出一个提示框。现在有两个疑问:
1、命令是如何与具体的功能关联?
2、该命令是如何添加到工具菜单?
对于第一个疑问:我们可以打开项目下以Package结尾的cs文件,该文件里有一个Initialize方法和一个MenuItemCallback事件处理方法,Package代码文件只有在我们点击命令的时候才会被
加载运行。当我们点击命令的时候会依次调用构造函数、Initialize方法、MenuItemCallBack事件处理方法,MenuItemCallBack事件处理方法就是在Initialize方法里与我们的命令进行关联。
对于第二个疑问:在项目的文件里我们可以找到一个以vsct(Visual Studio Command Table)为后缀的文件,命令就是通过该文件添加到工具菜单下的,项目在编译的时候会将该文件编译为二进制文件。
二、vsct文件简介
在vsct文件里,我们的菜单命令使用Button元素来表示的,如图-3所示:

图-4
Button元素的guid和id属性是该命令的唯一标识,这两个属性值分别在项目的Guids.cs和PkgCmdID.cs文件里定义了,priority表示命令在目标菜单的排列优先级。Parent子元素表示要将我们的命令添加到哪个菜单下面,如工具、帮助、右键菜单,id属性的值是Group元素的id属性值,如图-4所示。Icon元素是命令前的小图标,其属性值是在GuidSymbol元素定义的,如图-6所示。

图-5
Group元素定义了目标菜单的guid和id,也可以将图-4的guid和id换成guidSHLMainMenu和IDM_VS_MENU_TOOLS,这两种效果是一样的,都是将命令添加到右键菜单里。如果要按照图-4的方式设置guid和id值的话,需要事先知道目标菜单的guid和id值,并且要在Sysmbols元素里定义guid和id,如图-5所示:

图-6
除了红色框里的元素是我们自己定义的,其他的都是向导自动生成。那么为什么使用guidSHLMainMenu和IDM_VS_MENU_TOOLS作为guid和id两个属性的值的时候就不需要在Sysmbols元素里定义了呢?因为这两个元素的值已经在stdidcmd.h和vsshlids.h(C:\Program Files (x86)\Microsoft Visual Studio 12.0\VSSDK\VisualStudioIntegration\Common\Inc)这两个文件里定义了,而这两个文件已经在vsct文件的开头就已经使用Extern元素引入了,所以就不需要我们再去定义了。
三、如何获取目标菜单的guid和id值
1、打开注册表编辑器(打开运行窗口,输入regedit),在[HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\12.0\General]找到该路径,右击-新建-DWORD(32-位)值(D),建立一个注册文件,将其命名为EnableVSIPLogging,并将其值改为1。按下Ctrl+Shift,用鼠标点击VS里的菜单,就会弹出一个VSDebug Message窗口,如图-6所示:

图-7
其中Guid和CmdID值就是我们需要的,NameLoc表示我们点击的菜单名称。
四、设置命令只在xml文件的右键菜单里显示
由于命令关联的操作都是在点击命令的时候才调用的,所以要实现此功能需要四个步骤才能实现:
1、在Button元素加入子元素<CommandFlag>DynamicVisibility</CommandFlag>
2、为Package类加入特性ProvideAutoLoad,该特性表示当满足条件的时候,事先加载该类里的相关运行。而条件是由该特性的构造函数来设置的,相关的条件已经定义为UIContextGuids80抽象类的常量字段了。
3、将Initialize方法里的MenuCommand类改为OleMenuCommand类,并订阅OleMenuCommand类实例的BeforeQueryStatus事件,如图-8所示:

图-8
4、在BeforeQueryStatus事件处理函数里显示控制操作,如控制命令只在xml文件的右键菜单里才能显示,代码如下所示:
1 private void menuItem_BeforeQueryStatus(object sender, EventArgs e)
2 {
3 OleMenuCommand menuCommand = sender as OleMenuCommand;
4 if (menuCommand != null)
5 {
6 IntPtr hierarchyPtr, selectionContainerPtr;
7 uint projectItemId;
8 IVsMultiItemSelect mis;
9 IVsMonitorSelection monitorSelection = (IVsMonitorSelection)Package.GetGlobalService(typeof(SVsShellMonitorSelection));
10 monitorSelection.GetCurrentSelection(out hierarchyPtr, out projectItemId, out mis, out selectionContainerPtr);
11
12 IVsHierarchy hierarchy = Marshal.GetTypedObjectForIUnknown(hierarchyPtr, typeof(IVsHierarchy)) as IVsHierarchy;
13 if (hierarchy != null)
14 {
15 object value;
16 hierarchy.GetProperty(projectItemId, (int)__VSHPROPID.VSHPROPID_Name, out value);
17
18 if (value != null && value.ToString().EndsWith(".xml", StringComparison.OrdinalIgnoreCase))
19 {
20 menuCommand.Visible = true;
21 }
22 else
23 {
24 menuCommand.Visible = false;
25 }
26 }
27 }
28 }
到此,在xml文件的右键菜单里添加命令的功能已经实现。如图-9所示:

图-9
五、为命令添加关联功能
添加功能可以在MenuItemCallBack事件处理函数里进行操作,需要判断当前的xml文件是否是新建的,如果是需要加上根元素,为了防止用户是在根元素所在行的后面点击命令(这样就找不到根元素),所以在开始查找操作之前需要将光标移到第一行,然后根据查找的结果判断是否需要添加根元素。如果是新建的xml文件的话可以直接将xml元素信息添加到第一行后面,如果已经存在根元素,则将根元素的结束元素替换成xml元素信息,代码如下所示:
DTE dte = ServiceProvider.GlobalProvider.GetService(typeof(DTE)) as DTE;
if (dte == null)
return;
TextSelection ts = dte.ActiveDocument.Selection as TextSelection;
//防止用户在</mappings>结束符后进行操作,在结束符后操作的的FindText方法返回的结果为false
ts.MoveToLineAndOffset(1, 1);
bool result = ts.FindText("</mappings>",(int)vsFindOptions.vsFindOptionsMatchWholeWord);
if (!result)
{
if (ts.ActivePoint.Line == 1)
{
ts.EndOfLine();
ts.NewLine();
}
string str = "<mappings>\r\n" + sb.ToString();
ts.Insert(str);
}
else
{
//需要添加此操作,否则不会替换成功
ts.SelectAll();
ts.ReplacePattern("</mappings>", sb.ToString(), (int)vsFindOptions.vsFindOptionsMatchWholeWord);
}
VS2013在右键菜单添加命令插件开发的更多相关文章
- win7下给右键菜单添加启动cmd命令
		win7下给右键菜单添加启动cmd命令 (2013-07-20 19:20:56) 转载▼ 标签: it 右键 cmd 分类: 小软件操作技巧 最近编辑器在用windows下的gvim,但进入 ... 
- 系统右键菜单添加剪贴板清空项(隐藏DOS窗口)
		@color 0A @title 系统右键菜单添加剪贴板清空项(隐藏DOS窗口) by wjshan0808 @echo off echo 请输入右键菜单名称 set /p name= ::创建本机A ... 
- 《ArcGIS Engine+C#实例开发教程》第六讲 右键菜单添加与实现
		原文:<ArcGIS Engine+C#实例开发教程>第六讲 右键菜单添加与实现 摘要:在这一讲中,大家将实现TOCControl控件和主地图控件的右键菜单.在AE开发中,右键菜单有两种实 ... 
- 为Windows资源管理器右键菜单添加菜单项
		为Windows资源管理器右键菜单添加菜单项 在Windows下命令行用的比较多,经常在资源管理器里翻到某个目录,若想要在此目录下跑命令,只能是打开cmd.exe,然后一路cd才能到达此目录. 每次都 ... 
- 右键菜单添加带图标的Notepad++
		给Notepad++ 加带图标右键菜单 方式一: 拷贝以下代码建立一个reg文件,替换相关路径,保存,双击运行加入注册表 Windows Registry Editor Version 5.00 [H ... 
- Windows下给鼠标右键菜单添加获得完全控制权限的菜单项
		这段时间计算机C分区里多了很多无用的文件,而且不在同一个目录下,搜索出来删除的时候提示没有管理员权限,需要在右键属性里面修改,非常麻烦,于是查询了一下发现可以在文件右键菜单添加一个获取权限的菜单项,这 ... 
- VSTO 为Office已有右键菜单添加自己的菜单项(word,Excel)
		原文:VSTO 为Office已有右键菜单添加自己的菜单项(word,Excel) private void AddRightMenu() { Microsoft ... 
- 右键菜单添加包含ICON图片的快捷打开方式
		右键菜单添加包含ICON图片的快捷打开方式: ①保存如下代码为“submit.reg”, ②修改对应的程序地址 ③双击创建的文件,导入到注册表中,即可 Windows Registry Editor ... 
- vmware 安装不成功导致的问题解决以及右键菜单添加打开终端命令
		转自http://blog.csdn.net/puweilan/article/details/8609952 在VMware安装Ubuntu完成后,一直停留在VMware Easy Install, ... 
随机推荐
- 短视频 SDK 架构设计实践
			作者简介 孔维乐,七牛云客户端团队 Android 平台高级开发工程师,专注音视频,图形图像领域.OpenGL 专家,先后参与直播推流及连麦 SDK 的开发,主导短视频 SDK 的架构设计与实现, 对 ... 
- [HDU2157]How many ways??(DP + 矩阵优化)
			传送门 k < 20 k这么小,随便dp一下就好了... dp[i][j][k]表示从i到j经过k个点的方案数 4重循环.. 但是如果k很大就不好弄了 把给定的图转为邻接矩阵,即A(i,j)=1 ... 
- 八数码难题 双向搜索(codevs 1225)
			题目描述 Description Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.问题描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字 ... 
- 工具--IIS Express
			iisexpress-proxy https://github.com/icflorescu/iisexpress-proxy 适用于联调,比如app调用接口,开启端口后,app调用接口后会直接进入端 ... 
- 初学总结--------Java修饰符与修饰关键字(且叫修饰关键字)
			Java中有类,有成员变量,有成员方法,有局部变量.他们分别能用什么来修饰? 目前学习到的类,有普通类和内部类. 一.修饰普通类: 1.public 每个文件中只有一个类能被public修饰,表示可 ... 
- Java中的重写
			以下内容引用自http://wiki.jikexueyuan.com/project/java/overriding.html: 如果一个类从它的父类继承了一个方法,如果这个方法没有被标记为final ... 
- DTrace scripts for Mac OS X
			http://www.cnblogs.com/Proteas/p/3727297.html http://dtrace.org/blogs/brendan/2011/10/10/top-10-dtra ... 
- python解析xml文件之xml.etree.cElementTree和xml.etree.ElementTree区别和基本使用
			1.解析速度:ElementTree在 Python 标准库中有两种实现.一种是纯 Python 实现例如 xml.etree.ElementTree ,另外一种是速度快一点的 xml.etree.c ... 
- Swift初体验之HelloWord+苹果Swift编程语言新手教程【中文版】
			AppDelegate.swift : <span style="font-size:24px;"><strong>// // AppDelegate.sw ... 
- 使用引导光盘,将你的PC变身瘦客户机
			很多国内使用VMware View桌面虚拟化产品的朋友问我,是否可以将自己现有的PC改造成一台瘦客户机呢? 一方面即可以得到桌面虚拟化的管理,安全的好处,而且连前端PC机的系统管理的工作都省了? 答案 ... 
