You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VS2022 VSIX扩展自定义ToolWindowPane创建与注册求助

在VS2022 VSIX扩展中创建非文档形式的ToolWindowPane(类似NuGet窗口)

1. 创建ToolWindowPane子类

新建一个继承自ToolWindowPane的类,自定义窗口标题与UI内容(以WPF为例):

using Microsoft.VisualStudio.Shell;
using System.Windows;

namespace YourExtensionNamespace
{
    // 替换为自己生成的唯一GUID
    [Guid("F1234567-ABCD-EFGH-IJKL-MNOPQRSTUVWX")]
    public class CustomManagerWindow : ToolWindowPane
    {
        public CustomManagerWindow() : base(null)
        {
            Caption = "自定义管理窗口";
            // 绑定自定义WPF用户控件作为窗口内容
            Content = new CustomWindowControl();
        }
    }

    // 项目中添加的WPF用户控件,用于承载窗口UI
    public partial class CustomWindowControl : UserControl
    {
        public CustomWindowControl()
        {
            InitializeComponent();
            // 此处添加UI逻辑(如按钮、列表等)
        }
    }
}

2. 在Package类中注册窗口

找到项目中的Package类(通常命名为XXXPackage.cs),添加ProvideToolWindow属性,指定窗口样式为NonDocument(核心配置,确保窗口在文档区域以非文档形式展示):

using Microsoft.VisualStudio.Shell;
using System;
using System.Runtime.InteropServices;

namespace YourExtensionNamespace
{
    [PackageRegistration(UseManagedResourcesOnly = true)]
    // 替换为自己的Package GUID
    [Guid(YourExtensionPackage.PackageGuidString)]
    // 注册窗口,设置为非文档样式,可指定默认停靠方向
    [ProvideToolWindow(typeof(CustomManagerWindow), Style = ToolWindowStyle.NonDocument, Orientation = ToolWindowOrientation.Right)]
    [ProvideMenuResource("Menus.ctmenu", 1)]
    public sealed class YourExtensionPackage : Package
    {
        public const string PackageGuidString = "A1B2C3D4-E5F6-G7H8-I9J0-K1L2M3N4O5P6";

        protected override void Initialize()
        {
            base.Initialize();
            // 初始化触发窗口的命令(后续步骤实现)
            CustomWindowCommand.Initialize(this);
        }
    }
}

3. 添加触发窗口显示的命令

创建命令类,绑定菜单按钮点击事件以打开窗口:

using Microsoft.VisualStudio.Shell;
using System;
using System.ComponentModel.Design;

namespace YourExtensionNamespace
{
    internal sealed class CustomWindowCommand
    {
        // 自定义命令ID
        public const int CommandId = 0x0100;
        // 替换为自己的命令集GUID
        public static readonly Guid CommandSet = new Guid("ZYXWVUTSR-QPON-MLKJ-IHGF-DCBA76543210");

        private readonly Package _package;

        private CustomWindowCommand(Package package)
        {
            _package = package ?? throw new ArgumentNullException(nameof(package));
            if (_package.GetService(typeof(IMenuCommandService)) is OleMenuCommandService commandService)
            {
                var menuCommandId = new CommandID(CommandSet, CommandId);
                var menuItem = new MenuCommand(ShowToolWindow, menuCommandId);
                commandService.AddCommand(menuItem);
            }
        }

        public static CustomWindowCommand Instance { get; private set; }
        private IServiceProvider ServiceProvider => _package;

        public static void Initialize(Package package) => Instance = new CustomWindowCommand(package);

        private void ShowToolWindow(object sender, EventArgs e)
        {
            // 查找并显示ToolWindow
            var window = _package.FindToolWindow(typeof(CustomManagerWindow), 0, true);
            if (window?.Frame == null) throw new NotSupportedException("无法创建自定义窗口");
            
            var windowFrame = (IVsWindowFrame)window.Frame;
            Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(windowFrame.Show());
        }
    }
}

同时修改Menus.ctmenu文件,将命令添加到VS菜单(示例添加到Tools菜单):

<?xml version="1.0" encoding="utf-8"?>
<CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable">
  <Extern href="stdidcmd.h"/>
  <Extern href="vsshlids.h"/>
  <Commands package="guidYourExtensionPackage">
    <Groups>
      <Group guid="guidCustomWindowCommandSet" id="MyMenuGroup" priority="0x0600">
        <Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS"/>
      </Group>
    </Groups>
    <Buttons>
      <Button guid="guidCustomWindowCommandSet" id="CustomWindowCommandId" priority="0x0100" type="Button">
        <Parent guid="guidCustomWindowCommandSet" id="MyMenuGroup"/>
        <Strings>
          <ButtonText>打开自定义管理窗口</ButtonText>
        </Strings>
      </Button>
    </Buttons>
  </Commands>
  <Symbols>
    <GuidSymbol name="guidYourExtensionPackage" value="{A1B2C3D4-E5F6-G7H8-I9J0-K1L2M3N4O5P6}"/>
    <GuidSymbol name="guidCustomWindowCommandSet" value="{ZYXWVUTSR-QPON-MLKJ-IHGF-DCBA76543210}"/>
    <IDSymbol name="CustomWindowCommandId" value="0x0100"/>
    <IDSymbol name="MyMenuGroup" value="0x1020"/>
  </Symbols>
</CommandTable>

4. 调试测试

  1. 设置项目启动项:选择"启动外部程序",路径指向VS2022的devenv.exe(通常为C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\devenv.exe)
  2. 添加命令行参数:/rootsuffix Exp(启动实验性VS实例)
  3. 运行项目后,在VS的「工具」菜单中找到自定义命令,点击即可打开非文档形式的自定义窗口

快捷技巧

使用Extensibility Essentials 2022可以快速生成ToolWindow模板:右键项目→Add→New Item→选择Visual Studio Extensibility下的「Tool Window」,工具会自动生成基础代码,只需修改UI和注册属性即可。

内容的提问来源于stack exchange,提问作者Chris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 05:03:37