visual studio插件开发-Menu

工欲善其事,必先利其器,作为程序员我们很大部分时间在和ide打交道,好的插件可以大大提高我们的编程效率 , 我开发过几个vs插件来解决一键生成dbmodels,快速部署到服务器,总结下来最关键的还是对于Menu这块的扩展 , 因为这是插件功能的最常见的入口之一,下面给大家介绍vs插件各种menu的扩展
环境准备这里我使用vs2022版本 , 要开发vs插件的话,需要vs安装插件开发模块
打开vs 然后点击 工具 -> 获取工具和功能

visual studio插件开发-Menu

文章插图
然后勾选Visual Studio扩展开发
visual studio插件开发-Menu

文章插图
小试牛刀安装好之后,打开vs就可以选择到 vsix project 模板了

visual studio插件开发-Menu

文章插图
image
我们利用vsix project模板创建一个插件工程

visual studio插件开发-Menu

文章插图
image

visual studio插件开发-Menu

文章插图
image
  • MenuDemoVSIXPackage.cs(是插件的入口类)
  • source.extension.vsixmanifest(插件的描述 , 比如版本,说明等描述性配置的地方)
空的vsix project就创建成功了,我们添加一个command(菜单操作)

visual studio插件开发-Menu

文章插图
image

visual studio插件开发-Menu

文章插图
image
创建了一个Command会新增下面3个
  • 一个png (图标)
  • 一个vsct (不管几个Command都只会有一个这个文件 , 包含所有自定义菜单的配置)
  • TestCommand.cs (自定义菜单的命令 , 点击菜单的执行操作逻辑在里面)

visual studio插件开发-Menu

文章插图
image
点击启动这个插件,会打开一个有插件环境的vs(隔离的)
会看到我们的Command名称:Invoke TestCommand按钮在vs的[工具]这个菜单里面,点击它会出一个弹框,如下
visual studio插件开发-Menu

文章插图
好了,以上完成初体验后,回到本文要重点介绍:vs的Menu扩展
vs的Menu扩展上面我们说到 vsct文件 , 我们的按钮是展示在Vs哪种类型的Menu下 , 就是在这个文件定义的,我们一起看下这个vsct文件,关键部分我都用不同颜色来高亮显示

visual studio插件开发-Menu

文章插图
image
CommandTable 表示与VSPackage关联的所有命令、菜单组和菜单 。Extern 表示引用外部.h文件,最终会与.vsct文件合并的
  • stdidcmd.h
  • vsshlids.h
VSCT 编译器能使用 C++ 宏和预处理,通过extern引入头文件,比如vsshlids.h vsshlids.h 头文件位于
{VS安装目录}\VSSDK\VisualStudioIntegration\Common\Inc , 
例如我的目录是
C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VSSDK\VisualStudioIntegration\Common\Inc
vsct 文件中有用到宏 IDM_VS_MENU_TOOLS = 0x0005,
它表示 VS 上的 Tools 菜单的ID,这个宏即位于 vsshlids.h 头文件中 。
如果不引入这个头文件,那么就得写0x0005,导致可读性很差和难维护!

visual studio插件开发-Menu

文章插图
image
Commands 表示可以执行命令的集合 。每个命令都有以下四个子元素:
  • Menus 是菜单/工具栏的集合 。菜单是Commands的容器 。
  • Groups 决定菜单的位置
  • Buttons 表示命令按钮/菜单项
  • Bitmaps 按钮/菜单项的图标配置
CommandPlacements 指示各个命令应位于VSPackage菜单中的其他位置 。Symbols 包含包中所有命令的符号名和GUID, ID 。KeyBindings 快捷键指定 例如Ctrl+S 。以上vsct的xml scheme 的详细说明在这里有文档
https://github.com/MicrosoftDocs/visualstudio-docs/blob/main/docs/extensibility/internals/designing-xml-command-table-dot-vsct-files.md
一级菜单<Groups>  <Group guid="guidMenuDemoVSIXPackageCmdSet" id="MyMenuGroup" priority="0x0600">    <!-- 这个guid和id决定了菜单的位置 -->    <Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS"/>  </Group></Groups>

推荐阅读