Visual Studio 扩展入门(三)HelloWorld 下篇

本文通过实现Visual Studio启动记事本程序,来里了解Command模板的结构:

一、示例:实现“工具”菜单添加启动记事本程序的按钮

1、创建菜单命令

  1. 创建 VSIX 项目模板,并命名为FirstMenuCommand。
  2. 通过" Visual c # 项> Extensibility(扩展性) > Command(命令)",添加自定义命令 FirstCommand.cs。

此时解决方案目录如下:
image.png

2、修改FirstCommand .cs

  1. 添加命名空间。
using System.Diagnostics;
  1. 修改命令StartNotepadCmd的构造函数。
		private FirstCommand(AsyncPackage package, OleMenuCommandService commandService)
        {
            this.package = package ?? throw new ArgumentNullException(nameof(package));
            commandService = commandService ?? throw new ArgumentNullException(nameof(commandService));
            var menuCommandID = new CommandID(CommandSet, CommandId);
            //var menuItem = new MenuCommand(this.Execute, menuCommandID);//修改前
            var menuItem = new MenuCommand(this.StartNotepad, menuCommandID);//修改后
            commandService.AddCommand(menuItem);
        }
  1. 删除 Execute()方法并添加 StartNotepad()方法。使用类的实例 Process 来运行任何可执行文件,如:calc.exe。
       private void StartNotepad(object sender, EventArgs e)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            Process proc = new Process();
            proc.StartInfo.FileName = "notepad.exe";
            proc.Start();
        }

3、单击调试项目

实验实例中单击 "工具 > " "Invoke** **StartNotepadCmd" ,打开记事本。
image.png

二、Command模板代码结构

FirstCommand结构如下:

    internal sealed class FirstCommand
    {
        public const int CommandId = 0x0100;
        public static readonly Guid CommandSet = new Guid("562896fd-8a7a-4504-a749-a02ce7095683");
        private readonly AsyncPackage package;

        private FirstCommand(AsyncPackage package, OleMenuCommandService commandService){//...}

        public static FirstCommand Instance{get;private set;}

        private Microsoft.VisualStudio.Shell.IAsyncServiceProvider ServiceProvider{get{return this.package;}}
   
        public static async Task InitializeAsync(AsyncPackage package){//...};
    }
  • CommandId:命令ID。
  • CommandSet:命令菜单组(命令集GUID)。

与.vsct文件中IDSymbol 元素和GuidSymbol元素的 属性value相对应,在创建Command文件时,会自动一起创建。

         <GuidSymbol name="guidFirstMenuCommandPackageCmdSet" value="{562896fd-8a7a-4504-a749-a02ce7095683}">
          <IDSymbol name="MyMenuGroup" value="0x1020" />
          <IDSymbol name="FirstCommandId" value="0x0100" />
        </GuidSymbol>
  • package:提供这个命令的VSPackage,不为空。ServiceProvider属性返回它的服务接口。
  • InitializeAsync(AsyncPackage package):异步初始化命令的入口。由FirstMenuCommandPackage调用,在此方法内,会切换UI线程。获取菜单服务,调用构造传入参数,并通过AddCommand()添加菜单命令。


从示例一可以看到,若只修改Command脚本,是默认添加到“工具”菜单栏下面的,通过菜单篇可以了解更多的扩展菜单操作。

博客的示例源码:https://github.com/21thCenturyBoy/VSIX_HelloWorld

posted @ 2021-07-15 10:25  20世纪少年  阅读(106)  评论(0编辑  收藏  举报