Victor Havin
Victor Havin

Reputation: 1183

Getting debugger command from active project configuration

In a VSIX package I have to get the debugger command for active startup configuration. In other words, the command that would be executed when 'sturt under debugger' is selected. Using the code below I was able to get active configuration for startup project, but I can't figure out how to get the debugger command from IVSHierarchy representing the startup project. Is this even possible without going back to DTE?

private void GetStartupProject()
    {
        ThreadHelper.ThrowIfNotOnUIThread();
        IVsSolutionBuildManager bm = Package.GetGlobalService(typeof(IVsSolutionBuildManager)) as IVsSolutionBuildManager;
        int hr;
        IVsHierarchy project;
        hr = bm.get_StartupProject(out project);
        if (hr == VSConstants.S_OK)
        {
            project.GetProperty((uint)VSConstants.VSITEMID.Root, (int)__VSHPROPID.VSHPROPID_Name, out object projectName);
            IVsProjectCfg[] activeCfgs = new IVsProjectCfg[1];
            bm.FindActiveProjectCfg(IntPtr.Zero, IntPtr.Zero, project, activeCfgs);
            activeCfgs[0].get_DisplayName(out string activeCfgName);
            textOut.Text += String.Format("{0} {1}\r\n",(string)projectName, activeCfgName);
        }

    }

Upvotes: 0

Views: 231

Answers (2)

Victor Havin
Victor Havin

Reputation: 1183

After spending some time debugging and with help from Ed Dore, I was able to put together code that gets complete debugging command and working dir for native C++ and managed code projects:

    private void ListStartupProperties()
    {
        ThreadHelper.ThrowIfNotOnUIThread();
        IVsHierarchy vsHierarchy = null;
        int hresult = bm.get_StartupProject(out vsHierarchy);
        object objProject = null;
        if(vsHierarchy != null)
            hresult = vsHierarchy.GetProperty((uint)VSConstants.VSITEMID.Root, (int)__VSHPROPID.VSHPROPID_ExtObject, out objProject);
        Project startupProject = (Project)objProject;

        if (startupProject != null)
        {
            foreach (Property prop in startupProject.Properties)
            {
                try
                {
                    textOut.Text += string.Format("{0} = {1}\r\n", prop.Name, prop.Value);
                }
                catch (Exception e)
                {
                    textOut.Text += e.Message + "\r\n";
                }
            }
            string cmd = "";
            string args = "";
            string wd = "";
            VCProject vcp = startupProject.Object as VCProject;
            if (vcp != null)
            {   // This is VC project
                VCConfiguration vcc = vcp.ActiveConfiguration;
                VCDebugSettings dbg = vcc.DebugSettings;
                cmd = vcc.Evaluate(dbg.Command);
                args = vcc.Evaluate(dbg.CommandArguments);
                wd = vcc.Evaluate(dbg.WorkingDirectory);
            }
            else
            {   // Probably C# or VB
                Configuration cfg = startupProject.ConfigurationManager.ActiveConfiguration;
                ProjectConfigurationProperties cfgProperties = cfg.Object as ProjectConfigurationProperties;
                if (cfgProperties != null)
                {
                    string outPath = cfgProperties.OutputPath;
                    string localPath = startupProject.Properties.Item("FullPath").Value as string;
                    string outputName = startupProject.Properties.Item("OutputFileName").Value as string;
                    cmd = cfgProperties.StartProgram != "" ? 
                        cfgProperties.StartProgram :
                        localPath + outPath + outputName;
                    args = cfgProperties.StartArguments;
                    wd = cfgProperties.StartWorkingDirectory;
                }
            }
            textOut.Text += string.Format("StartProgram = {0}\r\n", cmd);
            textOut.Text += string.Format("StartArguments = {0}\r\n", args);
            textOut.Text += string.Format("WorkingDir = {0}\r\n", wd);
        }
    }

Upvotes: 1

Ed Dore
Ed Dore

Reputation: 2109

The IVsProjectCfg interface doesn't allow for enumerating the various configuration properties, or contain a method that would allow you to retrieve them. As you probably already suspect, the various project types expose their settings via automation, which for C# and VB.NET projects would correlate to using EnvDTE/VSLangProj interfaces to retrieve the specific debugger properties for a given configuration. For C#/VB.NET projects you'll want to retrieve/use the ProjectConfigurationProperties3 interface. For example:

private void OnGetDebuggerSettings(object sender, EventArgs e)
{
    ThreadHelper.ThrowIfNotOnUIThread();

    IVsHierarchy vsHierarchy = null;
    IVsSolutionBuildManager slnBuildMgr = (IVsSolutionBuildManager)GetService(typeof(SVsSolutionBuildManager));
    int hresult = slnBuildMgr.get_StartupProject(out vsHierarchy);
    object objProject = null;
    hresult = vsHierarchy.GetProperty((uint)VSConstants.VSITEMID.Root, (int)__VSHPROPID.VSHPROPID_ExtObject, out objProject);
    Project startupProject = (Project)objProject;

    // Note, cannot enumerate the ProjectConfigurationProperties, as it's not a collection interface
    // Refer to the documentation for ProjetConfigurationProperties3, or set a BP on the WriteLine below
    // and view the Dynamic View of the cfgProperties in the debugger's locals or watch window.
    Configuration cfg = startupProject.ConfigurationManager.ActiveConfiguration;
    ProjectConfigurationProperties3 cfgProperties = cfg.Object as ProjectConfigurationProperties3;
    if (cfgProperties!=null)
    {
        System.Diagnostics.Debug.WriteLine(cfgProperties.StartArguments);
    }
}

Hopefully that'll get you up and running.

Upvotes: 2

Related Questions