Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
414 views
in Technique[技术] by (71.8m points)

visual studio - How do I know from my VSIX that a build will be followed by a Debug session?

I'd like my VSIX does something different in my BuildEvents.OnBuildDone handler, if the build has been triggered because the user wants to start a Debug session.

I've tried...

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

...but unfortunately at that point m_DTE.Mode is not yet equal to vsIDEMode.vsIDEModeDebug.

I could start a one or two seconds timer and then check if (m_DTE.Mode == vsIDEMode.vsIDEModeDebug) but this is not a clean and reliable solution.

Can I know from querying the VSIX API somehow, either in BuildEvents.OnBuildBegin or BuildEvents.OnBuildDone handler, that a successful build will be followed by a Debug session?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can monitor Debug.Start command invocation with EnvDTE.CommandEvents. See the following sample C# extension for Visual Commander:

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;
}

On my machine the sequence of events is following:

  1. OnBeforeExecute Debug.Start
  2. OnBuildBegin
  3. OnAfterExecute Debug.Start
  4. OnBuildDone

So, if you see this sequence, it will be followed by a Debug session.


To complete the Serge answer. Actually I observe this order:

  1. OnBeforeExecute Debug.Start
  2. OnAfterExecute Debug.Start
  3. OnBuildBegin
  4. OnBuildDone

Moreover OnBuildBegin is skipped if VisualStudio estimates it has nothing to build before debugging.

OnBuildBegin or (if skipped) OnBuildDone is always executed just after OnAfterExecute Debug.Start (tested on VS2010/2012/2013/2015).

Spying others command, I can see two commands Build.SolutionConfigurations (and sometime also one or several Debug.StartupProject) are ran in between before/after execute Debug.Start (I observed this behavior only in in VS2013/2015).

  1. OnBeforeExecute Debug.Start
  2. OnBeforeExecute Build.SolutionConfigurations
  3. OnAfterExecute Build.SolutionConfigurations
  4. OnBeforeExecute Build.SolutionConfigurations
  5. OnAfterExecute Build.SolutionConfigurations
  6. OnBeforeExecute Debug.StartupProjects
  7. OnAfterExecute Debug.StartupProjects
  8. OnAfterExecute Debug.Start
  9. OnBuildBegin
  10. OnBuildDone

Hence we can infer that a successful build will be followed by a Debug session happens when one of these two events occurs:

  • when a Build.SolutionConfigurations or a Debug.StartupProjects command is triggered in between before/after Debug.Start command.
  • when there is less than a second between the last OnAfterExecute Debug.Start and the current OnBuildBegin or OnBuildDone.

As a side note the command Debug.StartWithoutDebugging plays the same role as Debug.Start when the user asks to start without debugging. Hence we can also infer a successful build will be followed by a run (with no debug) session


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...