从活动项目配置中获取调试器命令

Getting debugger command from active project configuration

在 VSIX 程序包中,我必须获取用于主动启动配置的调试器命令。换句话说,选择 'sturt under debugger' 时将执行的命令。使用下面的代码,我能够为启动项目获取活动配置,但我无法弄清楚如何从代表启动项目的 IVSHierarchy 获取调试器命令。这甚至可以不回到 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);
        }

    }

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。例如:

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

希望这能让你起床 运行。

在 Ed Dore 的帮助下花了一些时间进行调试后,我能够将代码放在一起,以获得完整的调试命令和本机 C++ 和托管代码项目的工作目录:

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