Overview:
Register for notifications at Visual Studio
Derive from notification interfaces:
class VisualStudioConnector
: Microsoft.VisualStudio.Shell.Interop.IVsSelectionEvents
, Microsoft.VisualStudio.Shell.Interop.IVsUpdateSolutionEvents
Advise for notifications:
private void ConnectWithVisualStudio()
{
bool connectedToSelectionEvents = false;
bool connectedToUpdateSolutionEvents = false;
m_monitorSelection = Microsoft.VisualStudio.Shell.ServiceProvider.GlobalProvider.
GetService(typeof(SVsShellMonitorSelection)) as IVsMonitorSelection;
if (m_monitorSelection != null)
{
m_monitorSelection.AdviseSelectionEvents(
this, out m_selectionEventsCookie);
connectedToSelectionEvents = true;
}
else
{
WriteLine(1, "ConnectWithVisualStudio: GetService(SVsShellMonitorSelection) failed!");
}
m_solutionBuildManager = Microsoft.VisualStudio.Shell.ServiceProvider.GlobalProvider.
GetService(typeof(SVsSolutionBuildManager)) as IVsSolutionBuildManager;
if (m_solutionBuildManager != null)
{
m_solutionBuildManager.AdviseUpdateSolutionEvents(
this, out m_updateSolutionEventsCookie);
connectedToUpdateSolutionEvents = true;
}
else
{
WriteLine(1, "ConnectWithVisualStudio: GetService(SVsSolutionBuildManager) failed!");
}
if (connectedToSelectionEvents && connectedToUpdateSolutionEvents)
{
WriteLine(1, "ConnectWithVisualStudio succeeded");
}
}
Unadvise from notifications:
public void DisconnectFromVisualStudio()
{
if (m_monitorSelection != null && m_selectionEventsCookie != 0)
m_monitorSelection.UnadviseSelectionEvents(m_selectionEventsCookie);
if (m_solutionBuildManager != null && m_updateSolutionEventsCookie != 0)
m_solutionBuildManager.UnadviseUpdateSolutionEvents(m_updateSolutionEventsCookie);
}
Receiving notifications from Visual Studio
Notification about a change of startup project:
int IVsSelectionEvents.OnElementValueChanged(
uint elementid, object varValueOld, object varValueNew)
{
if (elementid == (uint)VSConstants.VSSELELEMID.SEID_StartupProject)
{
if (varValueNew != null)
{
WriteLine(2, "Detected new StartupProject");
m_mainEvents.OnRefreshAll();
}
}
return VSConstants.S_OK;
}
int IVsSelectionEvents.OnCmdUIContextChanged(
uint dwCmdUICookie, int fActive)
{
return VSConstants.S_OK;
}
Notification about a change of configuration:
int IVsUpdateSolutionEvents.OnActiveProjectCfgChange(IVsHierarchy pIVsHierarchy)
{
WriteLine(2, "Detected OnActiveProjectCfgChange");
m_mainEvents.OnRefreshAll();
return VSConstants.S_OK;
}
Requesting project information via DTE
Get current configuration (e.g Debug or Release)
string configName = dte.Solution.SolutionBuild.ActiveConfiguration.Name;
Get name of startup project
EnvDTE80.SolutionBuild2 sb = (EnvDTE80.SolutionBuild2)dte.Solution.SolutionBuild;
if (sb == null)
{
WriteLine(1, "SolutionBuild is null (checking for startup project is not possible)");
return false;
}
if (sb.StartupProjects == null)
{
WriteLine(2, "ReadSettingsOfStartupProject-End: StartupProjects not available");
return false;
}
foreach (String item in (Array)sb.StartupProjects)
{
msg += item;
}
WriteLine(3, "startupProjects=" + msg);
Get startup project interface
EnvDTE.Project startupProj = FindProject(nameStartupProject);
Implementation detail: DTE allows iteration over projects
foreach (EnvDTE.Project project in dte.Solution.Projects)
Implementation detail: Hierarchical recursive search through tree of project items within method FindProjectRecursive:
foreach (EnvDTE.ProjectItem item in project.ProjectItems)
{
EnvDTE.Project realProject = item.Object as EnvDTE.Project;
if (realProject != null)
{
if (realProject.Kind == EnvDTE.Constants.vsProjectKindSolutionItems)
{
EnvDTE.Project projectNextLevel = FindProjectRecursive(
realProject, nameProject);
if (projectNextLevel != null)
{
return projectNextLevel;
}
}
else if (realProject.Name == nameProject)
{
return realProject;
}
}
}
Get name and path of generated executable (depends on previously found startupProj and configName)
Microsoft.VisualStudio.VCProjectEngine.VCProject vcProj =
(Microsoft.VisualStudio.VCProjectEngine.VCProject)startupProj.Object;
Microsoft.VisualStudio.VCProjectEngine.IVCCollection configs =
(Microsoft.VisualStudio.VCProjectEngine.IVCCollection)vcProj.Configurations;
Microsoft.VisualStudio.VCProjectEngine.VCConfiguration config =
FindConfig(configs, configName);
if (config == null)
{
WriteLine(1, "Config " + configName + " not found");
return false;
}
msg = "PrimaryOutput (FullExePath)=" + config.PrimaryOutput;
WriteLine(2, msg);
Helper function to find a given configuration
private Microsoft.VisualStudio.VCProjectEngine.VCConfiguration FindConfig(Microsoft.VisualStudio.VCProjectEngine.IVCCollection in_configurations, String in_configName)
{
WriteLine(3, "FindConfig: searching for config " + in_configName);
if ((in_configurations == null) || (in_configurations.Count <= 0))
{
WriteLine(3, "FindConfig: in_configurations is null or empty");
return null;
}
WriteLine(3, "FindConfig: configurations.Count=" + in_configurations.Count);
foreach (Microsoft.VisualStudio.VCProjectEngine.VCConfiguration configItem in in_configurations)
{
WriteLine(3, "FindConfig: configItem.Name=>" + configItem.Name + "< .ConfigurationName=>" + configItem.ConfigurationName + "<");
if (configItem.ConfigurationName == in_configName)
{
return configItem;
}
}
return null;
}
Automate Visual Studio
Open a text file within Visual Studio
public void OpenFile(string in_fullFilePath, int in_lineNum = 0)
{
WriteLine(3, "OpenFile " + in_fullFilePath + " line " + in_lineNum);
try
{
dte.ItemOperations.OpenFile(in_fullFilePath, EnvDTE.Constants.vsViewKindTextView);
if (in_lineNum>0)
{
dte.ExecuteCommand("Edit.Goto",in_lineNum.ToString());
}
}
catch (Exception ex)
{
WriteLine(1, "Could not open file " + in_fullFilePath + "\nEXCEPTION: " + ex.ToString());
}
}
Start debugging with special command line options
public void StartDebugging(string in_cmdLineParams)
{
try
{
if (m_startupProj != null)
{
string configName = dte.Solution.SolutionBuild.ActiveConfiguration.Name;
Microsoft.VisualStudio.VCProjectEngine.VCProject vcProj =
(Microsoft.VisualStudio.VCProjectEngine.VCProject)m_startupProj.Object;
Microsoft.VisualStudio.VCProjectEngine.IVCCollection configs =
(Microsoft.VisualStudio.VCProjectEngine.IVCCollection)vcProj.Configurations;
Microsoft.VisualStudio.VCProjectEngine.VCConfiguration config =
FindConfig(configs, configName);
Microsoft.VisualStudio.VCProjectEngine.VCDebugSettings dbgSettings =
(Microsoft.VisualStudio.VCProjectEngine.VCDebugSettings)config.DebugSettings;
dbgSettings.CommandArguments = in_cmdLineParams;
WriteLine(2, "StartDebugging: now starting debugger with dbgSettings.CommandArguments=" + dbgSettings.CommandArguments);
dte.Debugger.Go(false );
}
}
catch (Exception ex)
{
WriteLine(1, "Could not start debugging\nEXCEPTION: " + ex.ToString());
}
}