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

VSIX Community Toolkit无法为VS2022项目上下文菜单添加自定义命令

解决Visual Studio项目上下文菜单添加自定义命令的问题

一、修正VSCT文件的核心问题

你的VSCT文件无法显示命令的主要原因是父菜单节点指定错误,以及冗余的CommandPlacement配置。以下是修正后的完整代码:

<?xml version="1.0" encoding="utf-8"?>
<CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <Extern href="stdidcmd.h"/>
    <Extern href="vsshlids.h"/>
    <Include href="KnownImageIds.vsct"/>
    <Include href="VSGlobals.vsct"/>

    <Commands package="AnalyzerExtension">
        <Groups>
            <!-- 将组的父节点设为项目右键菜单的正确GUID/ID -->
            <Group guid="AnalyzerExtension" id="MyMenuGroup" priority="0x0001">
                <Parent guid="SHL_MenuGuid" id="IDM_VS_CTXT_PROJNODE"/>
            </Group>
        </Groups>

        <Buttons>
            <Button guid="AnalyzerExtension" id="MyCommand" priority="0x0100" type="Button">
                <Parent guid="AnalyzerExtension" id="MyMenuGroup" />
                <Icon guid="ImageCatalogGuid" id="StatusInformation" />
                <CommandFlag>IconIsMoniker</CommandFlag>
                <!-- 添加必要的命令标志,确保菜单可见且可交互 -->
                <CommandFlag>DynamicVisibility</CommandFlag>
                <CommandFlag>DefaultInvisible</CommandFlag>
                <Strings>
                    <ButtonText>执行代码分析</ButtonText>
                    <LocCanonicalName>.AnalyzerExtension.MyCommand</LocCanonicalName>
                </Strings>
            </Button>
        </Buttons>
    </Commands>

    <!-- 移除冗余的CommandPlacement,因为已经通过Group指定了父菜单 -->

    <Symbols>
        <GuidSymbol name="AnalyzerExtension" value="{5a8a77f2-be64-422c-9516-32e4cd00a008}">
            <IDSymbol name="MyMenuGroup" value="0x0001" />
            <IDSymbol name="MyCommand" value="0x0100" />
        </GuidSymbol>
    </Symbols>
</CommandTable>

关键修正点说明:

  • 父菜单节点修正:把原来的VSMainMenu/ItemNode替换为SHL_MenuGuid/IDM_VS_CTXT_PROJNODE,这是Visual Studio项目节点右键菜单的标准GUID/ID
  • 移除冗余配置:删除了不需要的CommandPlacements节点,因为按钮已经通过Group关联到正确的父菜单
  • 添加命令标志:增加DynamicVisibility和DefaultInvisible,确保菜单仅在选中项目时显示

二、实现命令点击后的代码分析逻辑

  1. 在Package类中绑定命令处理
    打开你的扩展Package类(通常是AnalyzerExtensionPackage.cs),在Initialize方法中注册命令执行的回调:
protected override void Initialize()
{
    base.Initialize();

    // 获取命令服务
    OleMenuCommandService commandService = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
    if (commandService != null)
    {
        // 定义命令ID
        CommandID menuCommandID = new CommandID(
            new Guid("{5a8a77f2-be64-422c-9516-32e4cd00a008}"), 
            0x0100); // 对应VSCT中的MyCommand ID

        // 创建菜单命令并绑定执行方法
        MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID);
        commandService.AddCommand(menuItem);
    }
}
  1. 实现代码分析的回调方法
    添加MenuItemCallback方法,获取当前选中的项目并执行代码分析逻辑:
private void MenuItemCallback(object sender, EventArgs e)
{
    // 获取当前选中的项目
    IVsHierarchy hierarchy = GetSelectedProject();
    if (hierarchy == null)
    {
        MessageBox.Show("请选择一个项目");
        return;
    }

    // 获取项目文件路径
    hierarchy.GetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ProjectDir, out object projectDirObj);
    string projectDir = projectDirObj as string;
    if (string.IsNullOrEmpty(projectDir)) return;

    // 执行你的代码分析逻辑
    RunCodeAnalysis(projectDir);

    MessageBox.Show("代码分析已完成");
}

// 辅助方法:获取当前选中的项目
private IVsHierarchy GetSelectedProject()
{
    IVsMonitorSelection monitorSelection = GetService(typeof(SVsShellMonitorSelection)) as IVsMonitorSelection;
    monitorSelection.GetCurrentSelection(out IntPtr hierarchyPtr, out uint itemId, out IVsMultiItemSelect multiSelect, out IntPtr selectionContainerPtr);

    try
    {
        if (hierarchyPtr != IntPtr.Zero)
        {
            return Marshal.GetObjectForIUnknown(hierarchyPtr) as IVsHierarchy;
        }
    }
    finally
    {
        if (hierarchyPtr != IntPtr.Zero)
            Marshal.Release(hierarchyPtr);
        if (selectionContainerPtr != IntPtr.Zero)
            Marshal.Release(selectionContainerPtr);
    }

    return null;
}

// 自定义代码分析方法
private void RunCodeAnalysis(string projectDir)
{
    // 在这里实现你的代码分析逻辑,例如遍历项目文件、调用分析工具等
    // 示例:遍历项目目录下的.cs文件
    foreach (string file in Directory.EnumerateFiles(projectDir, "*.cs", SearchOption.AllDirectories))
    {
        // 执行分析操作
        // ...
    }
}

三、验证与调试

  1. 重新生成解决方案,启动Visual Studio实验实例
  2. 在实验实例中右键点击任意项目,即可看到自定义的"执行代码分析"命令
  3. 点击命令,验证代码分析逻辑是否正常执行

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 19:05:38