本文分2部分 第一为自定义多项目模板 第二为vs add-in开发


效果图

1.自定义模板

2. 工具菜单

3.窗口

4.工程

5.文件

...


一. 多项目模板

单项目模板做起来很简单 选中一个项目在文件一栏中选中导出模板

然后选择项目模板

在最后一项向导会给出你的输出路径,一般都是系统的用户文档路径+\Visual Studio 2010\My Exported Templates

在对应目录下会生成你对应的项目模板压缩包

我们生成2个项目的模板文件 然后做一个多项目模板

我们解压2个模板文件并且放进一个新建的名称为MaoyaTemplates的文件夹 剪切到Visual Studio 2010\Templates\ProjectTemplates路径下

新建模板文件MyTemplate.vstemplate

根据要定义的模板内容 修改文件

然后将整个文件夹压缩成zip文件即可 在TemplateData可以定义一些自己需要的信息 例如icon定义你的模板图标 把图标文件放在相对路径即可

然后重新打开vs 即可看到刚才作成的模板

打开以后就是定义的2个demo工程 相当简单

这样就不用每次来新项目都去copy代码了


二 vs插件

概念性的东西可以参考 http://msdn.microsoft.com/zh-cn/library/bb384200.aspx

vs插件可以帮助或者优化你在vs开发过程的大部分窗口 它可以针对文件 针对项目 针对窗口 甚至针对不同的后缀做不同的处理

下面图文+代码介绍开发步骤(vs2010)

选择插件项目 进入向导根据自己的场景选择即可

中间向导过程略过 最后一步

完成向导后 默认工程框架如下

最关键的就是connect.cs文件

Connect 继承了2个类 IDTExtensibility2, IDTCommandTarget

IDTExtensibility2 包含在实现接口时用作事件的方法。 每当发生影响某个外接程序的事件时(如加载或卸载该外接程序时)以及对该外接程序进行任何更改时,Visual Studio 都会调用这些方法。

IDTCommandTarget 接口使开发者得以在环境中实现命名命令。 并且以定义命令状态或执行命令。

每个方法的描述

中文版可以参考msdn

http://msdn.microsoft.com/zh-cn/library/extensibility.idtextensibility2.aspx

http://msdn.microsoft.com/zh-cn/library/envdte.idtcommandtarget.aspx

其中我们作为入门开发 需要关注得的是

OnConnection 为IDTExtensibility2的 main 方法,这是因为每次加载外接程序时都会调用该方法。 该方法为外接程序在加载时的入口点,因此可以将要在外接程序启动时运行的任何代码放置在此处(或调用任何其他函数)。

void OnConnection(Object Application,ext_ConnectMode ConnectMode,Object AddInInst,ref Array custom
)

参数
Application
类型:System.Object
对集成开发环境 (IDE) 的一个实例 (DTE) 的引用,该实例是 Visual Studio 自动化模型的根对象。
ConnectMode
类型:Extensibility.ext_ConnectMode
一个 ext_ConnectMode 枚举值,指示向 Visual Studio 中加载外接程序的方式。
AddInInst
类型:System.Object
一个对外接程序自己的实例的 AddIn 引用。 此引用存储起来以供以后使用(如用于确定外接程序的父集合)。
custom
类型:System.Array
一个空数组,可用来传递在外接程序中使用的特定于主机的数据。

下面我们开始建一个工具栏(Tools)下的菜单

首先判断加载方式

if (connectMode == ext_ConnectMode.ext_cm_UISetup || connectMode == ext_ConnectMode.ext_cm_Startup ||connectMode == ext_ConnectMode.ext_cm_AfterStartup)

  这里的ConnectMode来自一个枚举 参考msdn http://msdn.microsoft.com/zh-cn/library/extensibility.ext_connectmode.aspx

然后添加注册插件命令和窗口 关键代码:

                    var toolsBar = commandBars[Tools];if (toolsBar != null){toolsSubPopup = (CommandBarPopup)toolsBar.Controls.Add(MsoControlType.msoControlPopup, Type.Missing, Type.Missing, 1, true);toolsSubPopup.Caption = MainMenuName;CommandBar toolsSubBar = toolsSubPopup.CommandBar;Command command = commands.AddNamedCommand2(_addInInstance,MenuName1,MenuName1,MenuName1,true,190,ref contextGUIDS,(int)vsCommandStatus.vsCommandStatusUnsupported + (int)vsCommandStatus.vsCommandStatusEnabled);command.AddControl(toolsSubBar);command = commands.AddNamedCommand2(_addInInstance,MenuName2,MenuName2,MenuName2,true,190,ref contextGUIDS,(int)vsCommandStatus.vsCommandStatusUnsupported + (int)vsCommandStatus.vsCommandStatusEnabled);command.AddControl(toolsSubBar, 2);}

  commandBars[Tools]表示命令栏中的工具栏,这里Tools实际为定义的字符串“Tools”。

  CommandBarPopup表示弹出命令条。

  _addInInstance表示当前插件实例。

  3个Menuname分别表示命令名称的缩写形式,UI显示的名称以及当用户将鼠标指针悬停在任何绑定到新命令的控件上时所显示的文本。

  true表示下面的190 为 Microsoft Office 位图的 ID。

  ContextUIGUIDs表示GUID 确定哪些环境上下文 (即调试模式,设计模式,等等) 显示命令。

  vsCommandStatusValue确定命令的禁用条件是不可见或禁用,当您提供一个 ContextUIGUIDs 参数,并且都不是当前活动的。

  AddNamedCommand2 创建命名命令,该命令由环境保存,并且在下次环境启动时(无论是否加载外接程序)可用。 外接程序以后可以通过响应 QueryStatus 方法来更改 ButtonText 名称。 如果文本以 # 开头,则该字符串的其余部分是一个整数,该整数表示外接程序已注册的附属 DLL 中的资源 ID。有两个默认值顺序状态:该默认值启用了状态和默认值可见性状态。 这些默认状态很重要,如果找不到命令处理程序 (因为该元素未加载或不实现 IDTCommandTarget)。 如果您的组件加载并实现 IDTCommandTarget,默认值不适用。

  Command.AddControl创建此命令的持久性命令栏控件。后面的数字表示菜单位置。

  详细参考http://msdn.microsoft.com/zh-cn/library/envdte80.commands2.addnamedcommand2.aspx

  这样基本上就完成了下图所示的效果

  但是我们需要对2个菜单进行功能型的开发

  QueryStatus方法返回指定的已命名命令的当前状态(启用、禁用、隐藏等)。

  在此方法添加片段

  if (neededText == vsCommandStatusTextWanted.vsCommandStatusTextWantedNone){if (commandName == GetCommandName(MainMenuName)){status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;return;}}

  vsCommandStatusSupported表示命令在此上下文中受支持,vsCommandStatusEnabled表示命令当前处于启用状态。

  Exec方法执行指定的命名命令。

            if (executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault){if (commandName == GetCommandName(MainMenuName)){MessageBox.Show("This is maoya test");handled = true;return;}if (commandName == GetCommandName(MenuName1)){MessageBox.Show("This is maoya Test1 test");handled = true;return;}if (commandName == GetCommandName(MenuName2)){MessageBox.Show("This is maoya Test2 test");handled = true;return;}}

  这里实现的很简单就是弹出个winform。你可以在这里实现很丰富的功能。


上面是工具栏的实现,下面介绍个操作窗口的

  Onconnection:

                    CommandBar mdiCommandBar = commandBars["Easy MDI Document Window"];if (mdiCommandBar != null){Command mdiCmd = commands.AddNamedCommand2(_addInInstance, MenuName3,MenuName3,MenuName3, false, 0,ref contextGUIDS);mdiCmd.AddControl(mdiCommandBar);}

  QueryStatus:

            if (commandName == GetCommandName(MenuName3) || commandName == GetCommandName(MenuName4) || commandName == GetCommandName(MenuName5)){status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;return;}

  Exec 功能是新建一个文件

            if (commandName == GetCommandName(MenuName3)){_applicationObject.ExecuteCommand("File.NewFile", string.Empty);handled = true;return;}

  


  下面我们在做一个针对项目工程的自定义按钮

  OnConnection:

 CommandBar projectBar = commandBars["Project"];if (projectBar != null){projectSubPopup = (CommandBarPopup)projectBar.Controls.Add(MsoControlType.msoControlPopup, Type.Missing, Type.Missing, 1, true);projectSubPopup.Caption = MainMenuName;CommandBar projectSubBar = projectSubPopup.CommandBar;Command projectCommand = commands.AddNamedCommand2(_addInInstance,MenuName4,MenuName4,MenuName4,true,190,ref contextGUIDS,(int)vsCommandStatus.vsCommandStatusUnsupported + (int)vsCommandStatus.vsCommandStatusEnabled);if (projectSubBar != null){projectCommand.AddControl(projectSubBar, 1);}}

  QueryStatus:

            if (commandName == GetCommandName(MenuName3) || commandName == GetCommandName(MenuName4) || commandName == GetCommandName(MenuName5)){status = vsCommandStatus.vsCommandStatusSupported | vsCommandStatus.vsCommandStatusEnabled;return;}

  Exec 这里可以抓到你选择的是哪一个项目 包括名称 路径等等 根据具体的需求再来处理对应的逻辑

  if (commandName == GetCommandName(MenuName4)){MessageBox.Show(string.Format("This is maoya {0} test,/r/n该项目名称为{1}", MenuName4, _applicationObject.SelectedItems.Item(1).Name));handled = true;return;}

  

  

类似的还有操作文件,代码就不贴了 直接上图

值得一提你可以利用文件后缀等做一些特殊操作

在QueryStatus方法中添加

            if (commandName == GetCommandName(MenuName6)){var uiHierarchy = (UIHierarchy)_applicationObject.Windows.Item(Constants.vsWindowKindSolutionExplorer).Object;if ((from UIHierarchyItem item in (Array)uiHierarchy.SelectedItems select item.Name).Any(itemName => itemName.IndexOf(".config") > -1)){status = vsCommandStatus.vsCommandStatusEnabled | vsCommandStatus.vsCommandStatusSupported;}}

  


希望对大家有帮助

vs多项目模板及add-in开发相关推荐

  1. vs2019新建一个html项目,VS2019 自定义项目模板的实现方法

    前言: 使用"宇宙最强IDE"开发项目时,都需要根据不同情况选择一个项目模板,来满足开发需求:如下 VS为我们提供了基础的项目模板,但现有项目模板未包含基础功能如:日志输出.审计日 ...

  2. Cookiecutter: 更好的项目模板工具:(1)简介及可用资源汇总

    原文档地址:https://cookiecutter.readthedocs.io/en/latest/ 本系列只介绍cookiecutter的基础使用,而且会删除与功能使用无关的部分.深度使用及了解 ...

  3. 后端开发实践:Spring Boot项目模板

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达今日推荐:2020年7月程序员工资统计,平均14357元,又跌了,扎心个人原创100W+访问量博客:点击前往,查看更多 作者 ...

  4. 后端开发实践:Spring Boot项目模板,拿去用吧!

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:干掉 Navicat:这个 IDEA 的兄弟真香!个人原创100W+访问量博客:点击前往,查看更多 作者:无知者 ...

  5. 从零开始实现ASP.NET Core MVC的插件式开发(二) - 如何创建项目模板

    标题:从零开始实现ASP.NET Core MVC的插件式开发(二) - 如何创建项目模板 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/11155 ...

  6. Java 后端开发实践 - 项目模板(16 步)

    在我的工作中,我从零开始搭建了不少软件项目,其中包含了基础代码框架和持续集成基础设施等,这些内容在敏捷开发中通常被称为"第0个迭代"要做的事情.但是,当项目运行了一段时间之后再来反 ...

  7. vs2017添加C语言模版,「vs2017 项目模板」有没有大神知道vs2017怎么配置wdk10开发x64驱动...

    vs2017 项目模板: 有没有大神知道vs2017怎么配置wdk10开发x64驱动 设置目标或测试计算机是配置计算机以便进行自动驱动程序部署.测试和调试的过程.一个测试和调试环境具有两台计算机:主计 ...

  8. 后端开发实践——Spring Boot项目模板

    在我的工作中,我从零开始搭建了不少软件项目,其中包含了基础代码框架和持续集成基础设施等,这些内容在敏捷开发中通常被称为"第0个迭代"要做的事情.但是,当项目运行了一段时间之后再来反 ...

  9. 后端开发实践系列——Spring Boot项目模板

    在我的工作中,我从零开始搭建了不少软件项目,其中包含了基础代码框架和持续集成基础设施等,这些内容在敏捷开发中通常被称为"第0个迭代"要做的事情.但是,当项目运行了一段时间之后再来反 ...

  10. Java后端开发实践-项目模板

    本文来源:http://r6d.cn/Jz79 整理出一套公共性的项目模板,旨在尽量多地包含日常开发所需,减少开发者的重复性工作以及提供一些最佳实践. 1. 从写好README开始 一个好的READM ...

最新文章

  1. healpy的安装(包括healpix)
  2. 位图 查找重复 排序 存数据
  3. 大数据入门笔记(三)
  4. C ++ STL中的set :: lower_bound()函数
  5. 软件测试——网络协议知识(二)
  6. Hbase ImmutableBytesWritable数据类型
  7. 如何在 Mac 上设置自定义锁屏信息?
  8. 用c语言编程设计简单的小游戏------走迷宫
  9. php 字符串长度函数
  10. 二维热传导 matlab,二维热传导方程数值解及MATLAB实现.docx
  11. python3传智播客_3.Ubuntu安装以及配置(传智播客.黑马程序员python学科)
  12. 主要发达国家大数据政策比较研究
  13. Fluent 旋转机械 风机 二维情况下的力矩计算算法
  14. windows下Elasticsearch安装、ElasticSearch-head插件安装使用
  15. 我的计算机梦想作文,我的梦想作文600字
  16. 基于 Java 的 I Don’t Wanna Be The Bugger 冒险游戏【100010211】
  17. 找出直系亲属 研究生机试 树
  18. 深入了解戴维斯双击和戴维斯双杀
  19. lcs算法c语言代码,LCS算法
  20. springboot 页面静态化

热门文章

  1. layer normalization 缺点_优缺点并存的星越,用车感受还是不错的!
  2. 惠普公司推出新的数据中心动态冷却技术
  3. 李洪强经典面试题32
  4. 获得数据库连接池中数据连接资源的两种方式
  5. [裴礼文数学分析中的典型问题与方法习题参考解答]4.3.24
  6. MySQL 效能监控工具--mysqlreport -转
  7. Qt编译时报堆空间不足
  8. bat 启动 不弹出对话框_跳过网易启动器用Steam启动逆水寒
  9. Logs Viewer
  10. linux下修改mysql数据存储_Linux下修改MySQL数据存放目录方法及可能遇到的问题--转...