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

开发Visual Studio 2022扩展:实现启动与无调试启动功能

实现VS2022扩展启动框模拟器选项与无调试支持的步骤

一、通过Command Table.vsct注册自定义启动选项

你拿到的GUID和CmdID分为两类:VS内置启动相关命令的标识(启动框下拉菜单、无调试启动按钮)和你需要自定义的模拟器命令标识。以下是配置示例:

  1. 定义自定义命令符号
    在<Symbols>节点下添加扩展专属GUID与命令ID,同时引用VS内置调试相关GUID:
<Symbols>
  <!-- VS内置调试命令组GUID -->
  <GuidSymbol name="guidVSDebugGroup" value="{1496A755-94DE-11D0-8C3F-00C04FC2AAE2}" />
  <!-- 你的扩展专属GUID(替换为VSIX项目自身GUID) -->
  <GuidSymbol name="guidMySimulatorExtensionCmdSet" value="{YOUR_EXTENSION_GUID}">
    <!-- 自定义模拟器命令ID -->
    <IDSymbol name="cmdidMyCustomSimulator" value="0x0100" />
  </GuidSymbol>
</Symbols>
  1. 将自定义选项添加到启动框下拉菜单
    在<Menus>节点中,把自定义命令作为子项挂载到启动框下拉菜单(使用你通过VSIPDebugging拿到的启动下拉菜单GUID和CmdID,示例为guidVSDebugGroup与IDM_VS_CTXT_DEBUGLAUNCH):
<Menus>
  <Menu guid="guidMySimulatorExtensionCmdSet" id="cmdidMyCustomSimulator" type="Menu">
    <Parent guid="guidVSDebugGroup" id="IDM_VS_CTXT_DEBUGLAUNCH" />
    <Strings>
      <ButtonText>我的自定义模拟器</ButtonText>
    </Strings>
  </Menu>
</Menus>
  1. 注册命令按钮
    在<Commands>节点下添加按钮定义,确保它显示在启动下拉列表中:
<Commands>
  <Button guid="guidMySimulatorExtensionCmdSet" id="cmdidMyCustomSimulator" priority="0x0100" type="Button">
    <Parent guid="guidVSDebugGroup" id="IDM_VS_CTXT_DEBUGLAUNCH" />
    <Icons />
    <Strings>
      <ButtonText>我的自定义模拟器</ButtonText>
      <CommandName>MyCustomSimulator</CommandName>
    </Strings>
  </Button>
</Commands>

二、在代码中处理启动逻辑(调试/无调试)

在Package类中注册命令回调,区分调试与无调试启动场景:

  1. 注册命令处理
    重写Initialize方法,注册自定义模拟器命令和无调试启动命令的回调:
protected override void Initialize()
{
    base.Initialize();

    var commandService = GetService(typeof(IMenuCommandService)) as OleMenuCommandService;
    if (commandService == null) return;

    // 注册自定义模拟器命令回调
    var simulatorCmdID = new CommandID(new Guid("YOUR_EXTENSION_GUID"), 0x0100);
    var simulatorMenuCmd = new OleMenuCommand(OnSimulatorLaunch, simulatorCmdID);
    simulatorMenuCmd.BeforeQueryStatus += OnSimulatorCmdBeforeQueryStatus;
    commandService.AddCommand(simulatorMenuCmd);

    // 注册无调试启动命令回调(使用你拿到的无调试启动按钮GUID和CmdID)
    var noDebugCmdID = new CommandID(new Guid("GUID_OF_STARTWITHOUTDEBUGGING"), CMDID_OF_STARTWITHOUTDEBUGGING);
    var noDebugMenuCmd = new OleMenuCommand(OnNoDebugLaunch, noDebugCmdID);
    commandService.AddCommand(noDebugMenuCmd);
}
  1. 过滤目标项目类型
    在OnSimulatorCmdBeforeQueryStatus中判断当前活动项目是否为目标类型,仅在符合条件时显示模拟器选项:
private void OnSimulatorCmdBeforeQueryStatus(object sender, EventArgs e)
{
    var menuCmd = sender as OleMenuCommand;
    if (menuCmd == null) return;

    var solutionService = GetService(typeof(SVsSolution)) as IVsSolution;
    solutionService.GetActiveProject(out var activeProject);
    if (activeProject == null)
    {
        menuCmd.Visible = false;
        return;
    }

    // 检查项目类型(替换为你的目标项目类型GUID)
    activeProject.GetProjectGuid(out var projectGuid);
    var targetProjectGuid = new Guid("YOUR_TARGET_PROJECT_TYPE_GUID");
    menuCmd.Visible = projectGuid == targetProjectGuid;
}
  1. 处理调试启动逻辑
    OnSimulatorLaunch方法处理点击自定义选项的调试启动:
private void OnSimulatorLaunch(object sender, EventArgs e)
{
    // 执行带调试的模拟器启动逻辑
    LaunchSimulator(debugMode: true);
}
  1. 处理无调试启动逻辑
    OnNoDebugLaunch方法先判断选中项是否为自定义模拟器,若是则执行无调试启动并阻止VS默认逻辑:
private void OnNoDebugLaunch(object sender, EventArgs e)
{
    if (IsCustomSimulatorSelected())
    {
        LaunchSimulator(debugMode: false);
        // 阻止VS默认无调试启动流程
        var menuCmd = sender as OleMenuCommand;
        menuCmd.Enabled = false;
        menuCmd.Visible = false;
    }
}

三、实现自动选择启动选项

通过VS UI自动化接口找到启动框下拉控件,设置选中项:

private void AutoSelectSimulatorOption()
{
    var uiShell = GetService(typeof(SVsUIShell)) as IVsUIShell;
    var cmdBarService = GetService(typeof(SVsCommandBar)) as IVsCommandBar;

    // 找到启动按钮所在命令栏(使用你拿到的启动框GUID和CmdID)
    cmdBarService.FindCommandBar(new Guid("GUID_OF_START_BAR"), CMDID_OF_START_DROPDOWN, out var commandBar);
    if (commandBar == null) return;

    var comboBox = commandBar.Controls.Item(1) as CommandBarComboBox;
    if (comboBox == null) return;

    // 遍历选项找到自定义模拟器并选中
    for (int i = 1; i <= comboBox.ListCount; i++)
    {
        if (comboBox.List[i] == "我的自定义模拟器")
        {
            comboBox.ListIndex = i;
            break;
        }
    }
}

关键注意事项

  • 确保VS内置命令的GUID和CmdID与VS2022版本匹配,VSIPDebugging获取的值需准确;
  • 调试与无调试启动逻辑要明确区分,无调试场景无需附加调试器;
  • 自动选择逻辑建议绑定到项目加载完成事件(如IVsSolutionEvents的OnAfterOpenProject)触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 09:35:14