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?
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:
Debug.Start
Debug.Start
So, if you see this sequence, it will be followed by a Debug session.
To complete the Serge answer. Actually I observe this order:
Debug.Start
Debug.Start
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).
Debug.Start
Build.SolutionConfigurations
Build.SolutionConfigurations
Build.SolutionConfigurations
Build.SolutionConfigurations
Debug.StartupProjects
Debug.StartupProjects
Debug.Start
Hence we can infer that a successful build will be followed by a Debug session happens when one of these two events occurs:
Build.SolutionConfigurations
or a Debug.StartupProjects
command is triggered in between before/after Debug.Start
command. 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