我如何从我的 VSIX 中知道构建之后将进行调试会话?

Pat*_*eam 1 debugging build visual-studio vsix

BuildEvents.OnBuildDone如果由于用户想要启动调试会话而触发了构建,我希望我的 VSIX 在我的处理程序中做一些不同的事情。

我试过了...

private void m_BuildEvents_OnBuildDone(vsBuildScope scope, vsBuildAction action) {
   if (m_DTE.Mode == vsIDEMode.vsIDEModeDebug) {
      //...
   }
}
Run Code Online (Sandbox Code Playgroud)

...但不幸的是在这一点m_DTE.Mode上还不等于vsIDEMode.vsIDEModeDebug.

我可以启动一个一两秒的计时器,然后检查是否(m_DTE.Mode == vsIDEMode.vsIDEModeDebug)但这不是一个干净可靠的解决方案。

我可以通过查询 VSIX API 以某种方式知道,无论是 inBuildEvents.OnBuildBegin还是BuildEvents.OnBuildDonehandler,成功的构建之后都会有一个 Debug 会话吗?

Ser*_*sov 5

您可以使用EnvDTE.CommandEvents监视Debug.Start命令调用。请参阅以下Visual Commander示例 C# 扩展:

public class E : VisualCommanderExt.IExtension
{
    public void SetSite(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package)
    {
        events = DTE.Events;
        commandEvents = events.get_CommandEvents(null, 0);
        buildEvents = events.BuildEvents;
        commands = DTE.Commands as EnvDTE80.Commands2;

        commandEvents.BeforeExecute += OnBeforeExecute;
        commandEvents.AfterExecute += OnAfterExecute;

        buildEvents.OnBuildDone += OnBuildDone;
        buildEvents.OnBuildBegin += OnBuildBegin;
    }

    public void Close()
    {
        commandEvents.BeforeExecute -= OnBeforeExecute;
        commandEvents.AfterExecute -= OnAfterExecute;

        buildEvents.OnBuildDone -= OnBuildDone;
        buildEvents.OnBuildBegin -= OnBuildBegin;
    }

    private void OnBeforeExecute(string Guid, int ID, object CustomIn, object CustomOut, ref bool CancelDefault)
    {
        string name = GetCommandName(Guid, ID);
        if (name == "Debug.Start")
        {
            System.Windows.MessageBox.Show("OnBeforeExecute Debug.Start");
        }
    }

    private void OnAfterExecute(string Guid, int ID, object CustomIn, object CustomOut)
    {
        string name = GetCommandName(Guid, ID);
        if (name == "Debug.Start")
        {
            System.Windows.MessageBox.Show("OnAfterExecute Debug.Start " + System.DateTime.Now.Second + "." + System.DateTime.Now.Millisecond);
        }
    }

    private void OnBuildDone(EnvDTE.vsBuildScope scope, EnvDTE.vsBuildAction action)
    {
        System.Windows.MessageBox.Show("OnBuildDone " + System.DateTime.Now.Second + "." + System.DateTime.Now.Millisecond);
    }

    private void OnBuildBegin(EnvDTE.vsBuildScope scope, EnvDTE.vsBuildAction action)
    {
        System.Windows.MessageBox.Show("OnBuildBegin " + System.DateTime.Now.Second + "." + System.DateTime.Now.Millisecond);
    }

    // throw()
    private string GetCommandName(string Guid, int ID)
    {
        if (Guid == null)
            return "null";

        string result = "";
        if (commands != null)
        {
            try
            {
                return commands.Item(Guid, ID).Name;
            }
            catch (System.Exception)
            {
            }
        }
        return result;
    }

    private EnvDTE.Events events;
    private EnvDTE.CommandEvents commandEvents;
    private EnvDTE.BuildEvents buildEvents;
    private EnvDTE80.Commands2 commands;
}
Run Code Online (Sandbox Code Playgroud)

在我的机器上,事件顺序如下:

  1. 执行前 Debug.Start
  2. 构建开始时
  3. 执行后执行 Debug.Start
  4. 建造完成

因此,如果您看到此序列,则后面将是调试会话。


完成塞尔吉的回答。其实我遵守这个顺序:

  1. 执行前 Debug.Start
  2. 执行后执行 Debug.Start
  3. 构建开始时
  4. 建造完成

此外OnBuildBegin,如果 VisualStudio 估计它在调试之前没有什么可构建的,则跳过。

OnBuildBegin或(如果跳过)OnBuildDone总是在 OnAfterExecute 之后执行Debug.Start(在 VS2010/2012/2013/2015 上测试)。

监视其他命令,我可以看到两个命令Build.SolutionConfigurations(有时也是一个或几个Debug.StartupProject)在执行之前/之后运行Debug.Start(我仅在 VS2013/2015 中观察到这种行为)。

  1. 执行前 Debug.Start
  2. 执行前 Build.SolutionConfigurations
  3. 执行后执行 Build.SolutionConfigurations
  4. 执行前 Build.SolutionConfigurations
  5. 执行后执行 Build.SolutionConfigurations
  6. 执行前 Debug.StartupProjects
  7. 执行后执行 Debug.StartupProjects
  8. 执行后执行 Debug.Start
  9. 构建开始时
  10. 建造完成

因此,我们可以推断,当发生以下两个事件之一时,成功构建之后将发生Debug 会话

  • 当一个Build.SolutionConfigurations或一个Debug.StartupProjects命令在Debug.Start命令之前/之后被触发时。
  • 当最后一个 OnAfterExecuteDebug.Start和当前OnBuildBeginor之间的时间少于一秒时OnBuildDone

附带说明一下,该命令Debug.StartWithoutDebugging的作用Debug.Start与用户要求在不进行调试的情况下启动时的作用相同。因此,我们还可以推断成功的构建之后将有一个运行(没有调试)会话