none
Envdte Trying to reach project.StartOptions Cant access ConfigurationManager

    Question

  • I'm writing a c# console application with envdte / envdte80 (no experience with both) to open a project inside a new Visual Studio Instance. Inside this new instance, I'm trying to change the Project.StartOptions through my console application.

    When I try to load the ConfigurationManager, I'm receiving this exception:
    "System.InvalidOperationException",
    "Operation is not valid due to the current state of the object."

    My Code:
        
    using EnvDTE;
    using EnvDTE80;
    using System;
    
    namespace AutomationProject
    {
        class Program
        {
            static void Main(string[] args)
            {
                ...
                EnvDTE80.DTE2 dte;
                object obj = null;
                System.Type t = System.Type.GetTypeFromProgID("VisualStudio.DTE.14.0", true);
                System.Threading.Thread.Sleep(1000);
                // Attempt to create an instance of envDTE. 
                obj = System.Activator.CreateInstance(t, true);
    
                // Cast to DTE2.
                dte = (EnvDTE80.DTE2)obj;
                dte.MainWindow.Visible = true;
                //dte.MainWindow.Activate();
                //dte.UserControl = true;
                dte.ExecuteCommand("File.OpenProject", projectLocation + projectName);
                
                //dte.ExecuteCommand("Project.StartOptions", "-break -lib:ModuleName -exec:TestName");
                // Get a reference to the solution2 object.
                System.Threading.Thread.Sleep(1000);
                Solution2 soln = (Solution2)dte.Solution;
                Project proj = soln.Projects.Item(1);
                try
                {
                   dte.Solution.SolutionBuild.SolutionConfigurations.Item(1).Activate();
                    ConfigurationManager configmgr;
                    Configuration config;
                    if (dte.Solution.Projects.Count > 0)
                    {
                        configmgr = dte.Solution.Projects.Item(1).ConfigurationManager;
                        config = proj.ConfigurationManager.ActiveConfiguration;
                        config.Properties.Item("StartArguments").Value = "command line arguments";
                    ...
                    }
                ...
                }
            ...
            }
        }
    }


    Wednesday, April 5, 2017 10:22 AM

All replies

  • Is there any reason why you need to open VS to make these changes? Especially with the changes in newer versions of VS where everything is async, simply sleeping to get VS time to load the projects isn't sufficient. This is especially true if lightweight solution loading is turned on.

    //Add Microsoft.Build.Framework NuGet package first
    using Microsoft.Build.Construction;
    
    static void Main ( string[] args )
    {
        var filePath = @"project filepath";
    
        //Open the project
        var project = ProjectRootElement.Open(filePath);
    
        //Find all property groups that are related to a configuration            
        var configurations = FindConfigurations(project.PropertyGroups);
        foreach (var config in configurations)
        {
            //Get the existing startup options, if nay
            var startupOptions = FindProperty(config, "StartArguments");
    
            //Add or update it
            if (startupOptions != null)
                startupOptions.Value = "arguments";
            else
                config.AddProperty("StartArguments", "arguments");                                
        };
    
        //Save changes
        project.Save();
    }
    
    //Could be extension methods...
    static IEnumerable<ProjectPropertyGroupElement> FindConfigurations ( IEnumerable<ProjectPropertyGroupElement> groups )
    {
        foreach (var group in groups)
        {
            if (!String.IsNullOrEmpty(group.Condition) && group.Condition.IndexOf("$(Configuration)", StringComparison.OrdinalIgnoreCase) >= 0)
                yield return group;
        };
    }
    
    static ProjectPropertyElement FindProperty ( ProjectPropertyGroupElement source, string propertyName )
    {
        return source.Properties.FirstOrDefault(p => String.Compare(p.Name, propertyName, true) == 0);
    }

    Michael Taylor
    http://www.michaeltaylorp3.net

    Wednesday, April 5, 2017 5:18 PM
    Moderator