In seamless non-destructive debugging scenarios (macro
recording and running) the host application must keep track of the latest
version of the “macro” project assembly. The IDE offers the user many opportunities
to change settings like the active configuration or the output path which can
make it difficult for the host to find the latest version of the assembly.
To make it more complicated, when the advanced build
configurations are not shown the build path is dependent on the context of the
build (this mirrors Visual Studio).
Specifically, if the user starts debugging with F5, the project builds
to the debug configuration output path; however, if the user builds through the
menu the project builds to the release output path. Very complicated.
The good news is there are a couple of events a host can
hook into through DTE.BuildEvents which can be used to determine the build
location. These events are the
OnBuildProjConfigBegin and OnBuildProjConfigDone events (you should only need
to hook into one of these). Below is
code from a modified ShapeAppCSharp sample (this will work for VSTA v 1 and v
2) which catches these events and outputs the configuration and build path for
the macro project.
private void EnsureIDE()
{
if (this.dte == null)
{
try
{
IDTEProvider dteProvider = (IDTEProvider)new
VSTADTEProviderClass();
this.dte = (EnvDTE.DTE)dteProvider.GetDTE("ShapeAppCSharp",
0);
System.Diagnostics.Debug.Assert(this.dte != null);
}
catch
{
// If DTEProvider does not work, try
co-creating DTE instead.
object objDTE = new
DTE();
this.dte = (EnvDTE.DTE)objDTE;
}
// Save a copy of the event sync locations so they don't
get
// garbage collected.
this.buildEvents = dte.Events.BuildEvents;
this.solutionEvents = dte.Events.SolutionEvents;
this.dteEvents = dte.Events.DTEEvents;
this.buildEvents.OnBuildDone += new
EnvDTE._dispBuildEvents_OnBuildDoneEventHandler(BuildEvents_OnBuildDone);
this.solutionEvents.AfterClosing += new
EnvDTE._dispSolutionEvents_AfterClosingEventHandler(solutionEvents_AfterClosi
ng);
this.dteEvents.OnBeginShutdown
+= new
EnvDTE._dispDTEEvents_OnBeginShutdownEventHandler(dteEvents_OnBeginShutdown);
this.buildEvents.OnBuildProjConfigBegin += new
EnvDTE._dispBuildEvents_OnBuildProjConfigBeginEventHandler(buildEvents_OnBuil
dProjConfigBegin);
this.buildEvents.OnBuildProjConfigDone += new
EnvDTE._dispBuildEvents_OnBuildProjConfigDoneEventHandler(buildEvents_OnBuild
ProjConfigDone);
}
}
void
buildEvents_OnBuildProjConfigDone(string
Project, string ProjectConfig,
string Platform, string SolutionConfig, bool
Success)
{
System.Diagnostics.Debug.Write("\n\n Try OnBuildProjconfigDone");
System.Diagnostics.Debug.Write("\n\t ProjectConfig " + ProjectConfig);
System.Diagnostics.Debug.Write("\n\t SolutionConfig " +
SolutionConfig);
GetAssemblyPath(macroProject);
}
void
buildEvents_OnBuildProjConfigBegin(string
Project, string ProjectConfig,
string Platform, string SolutionConfig)
{
System.Diagnostics.Debug.Write("\n\n Try OnBuildProjConfigBegin");
System.Diagnostics.Debug.Write("\n\t ProjectConfig " + ProjectConfig);
System.Diagnostics.Debug.Write("\n\t SolutionConfig " +
SolutionConfig);
GetAssemblyPath(macroProject);
}
static string GetAssemblyPath(EnvDTE.Project vsProject)
{
string fullPath = vsProject.Properties.Item("FullPath").Value.ToString();
string outputPath =
vsProject.ConfigurationManager.ActiveConfiguration.Properties.Item("OutputPat
h").Value.ToString();
string outputDir = Path.Combine(fullPath,
outputPath);
string outputFileName =
vsProject.Properties.Item("OutputFileName").Value.ToString();
string assemblyPath = Path.Combine(outputDir,
outputFileName);
System.Diagnostics.Debug.Write("\n\n Try #");
System.Diagnostics.Debug.Write("\n ActiveConfig:
" +
vsProject.ConfigurationManager.ActiveConfiguration.ConfigurationName);
System.Diagnostics.Debug.Write("\n fullPath: " + fullPath);
System.Diagnostics.Debug.Write("\n outputPath: " + outputPath);
System.Diagnostics.Debug.Write("\n outputDir: " + outputDir);
System.Diagnostics.Debug.Write("\n outputFileName: " + outputFileName);
System.Diagnostics.Debug.Write("\n assemblyPath: " + assemblyPath);
return assemblyPath;
}
Posted
Jun 13 2008, 03:04 PM
by
Melody