public static Project[] GetProjects(SolutionFile solution, IDictionary<string, string> args)
 {
     return solution.ProjectsInOrder
         .Where(p => p.ProjectType != SolutionProjectType.SolutionFolder)
         .Select(p => LoadProject(p.AbsolutePath, SpecializeArgsForSolutionProject(solution, p, args)))
         .ToArray();
 }
Exemple #2
0
        /// <summary>
        /// Read the file.
        /// </summary>
        /// <param name="filename">The filename of the .sln.</param>
        public SolutionFile(string filename)
        {
            // SolutionFile.Parse() expects a rooted path.
            var fullPath = Path.GetFullPath(filename);

            solutionFile = Microsoft.Build.Construction.SolutionFile.Parse(fullPath);
        }
Exemple #3
0
        private void ValidateProjectInSolution(Action <SlnProject, ProjectInSolution> customValidator, SlnProject[] projects, bool folders)
        {
            string solutionFilePath = GetTempFileName();

            SlnFile slnFile = new SlnFile();

            slnFile.AddProjects(projects);
            slnFile.Save(solutionFilePath, folders);

            MSBuildSolutionFile solutionFile = MSBuildSolutionFile.Parse(solutionFilePath);

            foreach (SlnProject slnProject in projects)
            {
                solutionFile.ProjectsByGuid.ContainsKey(slnProject.ProjectGuid.ToSolutionString()).ShouldBeTrue();

                ProjectInSolution projectInSolution = solutionFile.ProjectsByGuid[slnProject.ProjectGuid.ToSolutionString()];

                projectInSolution.AbsolutePath.ShouldBe(slnProject.FullPath);
                projectInSolution.ProjectGuid.ShouldBe(slnProject.ProjectGuid.ToSolutionString());
                projectInSolution.ProjectName.ShouldBe(slnProject.Name);

                IEnumerable <string> configurationPlatforms = from configuration in slnProject.Configurations from platform in slnProject.Platforms select $"{configuration}|{platform}";

                configurationPlatforms.ShouldBe(projectInSolution.ProjectConfigurations.Keys, ignoreOrder: true);

                customValidator?.Invoke(slnProject, projectInSolution);
            }
        }
        private async Task CreateProjectsAsync(SolutionFile solution, SolutionTemplateInfo solutionTemplateInfo)
        {
            var folders = new Dictionary<Guid, SolutionFolderTemplateInfo>();
            folders.Add(Guid.Empty, solutionTemplateInfo);

            foreach (var proj in solution.ProjectsInOrder)
            {
                await CreateSolutionItemTemplateInfoAsync(solution, solutionTemplateInfo, proj, folders);
            }
        }
 string GetNameOfMissing(SolutionFile solution, String guid)
 {
   Regex re_name = new Regex(@"<ProjectReference.*?<Project>"+guid+"</Project>.*?<Name>(?'name'.*?)</Name>.*?</ProjectReference>",
                             RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline);
                           
   foreach(var project in solution.ProjectsInOrder.Where(IsCsharpProject))
     foreach (Match m in re_name.Matches(File.ReadAllText(project.AbsolutePath)))
       return m.Groups["name"].Value;
   return "unresolved name";
 }
 private static IDictionary<string, string> SpecializeArgsForSolutionProject(SolutionFile solution, ProjectInSolution p, IDictionary<string, string> args)
 {
     var targetPlatform = args.ContainsKey("Platform") ? args["Platform"] : solution.GetDefaultPlatformName();
     var targetConfiguration = args.ContainsKey("Configuration") ? args["Configuration"] : solution.GetDefaultConfigurationName();
     var targetSolutionConfiguration =
         solution.SolutionConfigurations.FirstOrDefault(conf => conf.ConfigurationName == targetConfiguration && conf.PlatformName == targetPlatform)?.FullName;
     var foo = targetSolutionConfiguration == null || !p.ProjectConfigurations.ContainsKey(targetSolutionConfiguration) ? null : p.ProjectConfigurations[targetSolutionConfiguration];
     var copy = new Dictionary<string, string>(args);
     copy["Platform"] = foo == null ? targetPlatform : foo.PlatformName;
     copy["Configuration"] = foo == null ? targetConfiguration : foo.ConfigurationName;
     return copy;
 }
        private async Task<SolutionItemTemplateInfo> CreateSolutionItemTemplateInfoAsync(
            SolutionFile solution,
            SolutionTemplateInfo solutionTemplateInfo,
            ProjectInSolution proj,
            IDictionary<Guid, SolutionFolderTemplateInfo> folders)
        {
            var id = Guid.Parse(proj.ProjectGuid);
            var parentId = proj.ParentProjectGuid == null ? Guid.Empty : Guid.Parse(proj.ParentProjectGuid);

            SolutionFolderTemplateInfo folder;
            if (!folders.TryGetValue(parentId, out folder))
            {
                ProjectInSolution parentProj;
                if (solution.ProjectsByGuid.TryGetValue(proj.ParentProjectGuid, out parentProj))
                {
                    folder = (SolutionFolderTemplateInfo)await CreateSolutionItemTemplateInfoAsync(solution, solutionTemplateInfo, parentProj, folders);
                }
            }

            Debug.Assert(folder != null);

            SolutionItemTemplateInfo result;

            switch (proj.ProjectType)
            {
                case SolutionProjectType.KnownToBeMSBuildFormat:
                    Project project = new Project(proj.AbsolutePath);
                    var rootNamespace = project.Properties.Single(x => x.Name == "RootNamespace").EvaluatedValue;
                    var targetName = project.Properties.Single(x => x.Name == "TargetName").EvaluatedValue;
                    var rootName = AddRootName(rootNamespace, solutionTemplateInfo);
                    result = new ProjectTemplateInfo(id, proj.ProjectName)
                    {
                        NameWithoutRoot = targetName.Substring(rootName.Length + 1),
                        FileName = proj.AbsolutePath,
                        ProjectConfigurations = GetProjectConfigurations(proj.ProjectConfigurations)
                    };
                    break;
                case SolutionProjectType.SolutionFolder:
                    if (folders.ContainsKey(id))
                    {
                        return folders[id];
                    }
                    result = new SolutionFolderTemplateInfo(id, proj.ProjectName);
                    folders.Add(id, (SolutionFolderTemplateInfo)result);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            folder.Items.Add(result);

            return result;
        }
 bool AreAllReferencedProjectsPresent(SolutionFile solution)
 {
   foreach(var project in solution.ProjectsInOrder.Where(IsCsharpProject))
   {
     if (!File.Exists(project.AbsolutePath))
     {
       _logger.LogErr("Error SV001: Missing file {0}", project.AbsolutePath);
       return false;
     }
   }
   return true;
 }
        public void ParseFirstProjectLine_VC()
        {
            SolutionFile p = new SolutionFile();
            p.FullPath = "c:\\foo.sln";
            ProjectInSolution proj = new ProjectInSolution(p);

            p.ParseFirstProjectLine
            (
                "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"Project name.vcproj\", \"Relative path\\to\\Project name.vcproj\", \"Unique name-GUID\"",
                 proj
            );

            Assert.Fail("Should not get here");
        }
        private static List<string> GetParentFolderChain(SolutionFile solutionFile, ProjectInSolution project)
        {
            var parentFolderChain = new List<string>();
            var parentGuid = project.ParentProjectGuid;
            ProjectInSolution parentFolder;

            while (!string.IsNullOrEmpty(parentGuid) && solutionFile.ProjectsByGuid.TryGetValue(parentGuid, out parentFolder) && parentFolder != null)
            {
                parentFolderChain.Add(parentFolder.ProjectName);
                parentGuid = parentFolder.ParentProjectGuid;
            }

            parentFolderChain.Reverse();
            return parentFolderChain;
        }
        /// <summary>
        /// Loads the <see cref="SolutionInfo"/> for the specified solution file, including all projects referenced by the solution file and
        /// all the projects referenced by the project files.
        /// </summary>
        public async Task <SolutionInfo> LoadSolutionInfoAsync(
            string solutionFilePath,
            CancellationToken cancellationToken = default(CancellationToken))
        {
            if (solutionFilePath == null)
            {
                throw new ArgumentNullException(nameof(solutionFilePath));
            }

            var absoluteSolutionPath = this.GetAbsoluteSolutionPath(solutionFilePath, Directory.GetCurrentDirectory());

            using (_dataGuard.DisposableWait(cancellationToken))
            {
                this.SetSolutionProperties(absoluteSolutionPath);
            }

            VersionStamp version = default(VersionStamp);

            Microsoft.Build.Construction.SolutionFile solutionFile = Microsoft.Build.Construction.SolutionFile.Parse(absoluteSolutionPath);
            var reportMode = this.SkipUnrecognizedProjects ? ReportMode.Log : ReportMode.Throw;

            // a list to accumulate all the loaded projects
            var loadedProjects = new LoadState(null);

            // load all the projects
            foreach (var project in solutionFile.ProjectsInOrder)
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (project.ProjectType != SolutionProjectType.SolutionFolder)
                {
                    var projectAbsolutePath = TryGetAbsolutePath(project.AbsolutePath, reportMode);
                    if (projectAbsolutePath != null)
                    {
                        IProjectFileLoader loader;
                        if (TryGetLoaderFromProjectPath(projectAbsolutePath, reportMode, out loader))
                        {
                            // projects get added to 'loadedProjects' as side-effect
                            // never prefer metadata when loading solution, all projects get loaded if they can.
                            var tmp = await GetOrLoadProjectAsync(projectAbsolutePath, loader, preferMetadata : false, loadedProjects : loadedProjects, cancellationToken : cancellationToken).ConfigureAwait(false);
                        }
                    }
                }
            }

            // construct workspace from loaded project infos
            return(SolutionInfo.Create(SolutionId.CreateNewId(debugName: absoluteSolutionPath), version, absoluteSolutionPath, loadedProjects.Projects));
        }
        public void ParseFirstProjectLine_VC2()
        {
            SolutionFile p = new SolutionFile();
            p.FullPath = "c:\\foo.sln";
            ProjectInSolution proj = new ProjectInSolution(p);

            p.ParseFirstProjectLine
            (
                "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"Project name.myvctype\", \"Relative path\\to\\Project name.myvctype\", \"Unique name-GUID\"",
                 proj
            );
            Assert.AreEqual(SolutionProjectType.KnownToBeMSBuildFormat, proj.ProjectType);
            Assert.AreEqual("Project name.myvctype", proj.ProjectName);
            Assert.AreEqual("Relative path\\to\\Project name.myvctype", proj.RelativePath);
            Assert.AreEqual("Unique name-GUID", proj.ProjectGuid);
        }
        public void BasicParseFirstProjectLine()
        {
            SolutionFile p = new SolutionFile();
            p.FullPath = "c:\\foo.sln";
            ProjectInSolution proj = new ProjectInSolution(p);

            p.ParseFirstProjectLine
            (
                "Project(\"{Project GUID}\") = \"Project name\", \"Relative path to project file\", \"Unique name-GUID\"",
                 proj
            );
            Assert.AreEqual(SolutionProjectType.Unknown, proj.ProjectType);
            Assert.AreEqual("Project name", proj.ProjectName);
            Assert.AreEqual("Relative path to project file", proj.RelativePath);
            Assert.AreEqual("Unique name-GUID", proj.ProjectGuid);
        }
Exemple #14
0
        private void ValidateProjectInSolution(Action <SlnProject, ProjectInSolution> customValidator, SlnProject[] projects)
        {
            string solutionFilePath = GetTempFileName();

            SlnFile slnFile = new SlnFile(projects);

            slnFile.Save(solutionFilePath);

            MSBuildSolutionFile solutionFile = MSBuildSolutionFile.Parse(solutionFilePath);

            foreach (SlnProject slnProject in projects)
            {
                solutionFile.ProjectsByGuid.ContainsKey(slnProject.ProjectGuid).ShouldBeTrue();

                ProjectInSolution projectInSolution = solutionFile.ProjectsByGuid[slnProject.ProjectGuid];

                projectInSolution.AbsolutePath.ShouldBe(slnProject.FullPath);
                projectInSolution.ProjectGuid.ShouldBe(slnProject.ProjectGuid);
                projectInSolution.ProjectName.ShouldBe(slnProject.Name);

                customValidator?.Invoke(slnProject, projectInSolution);
            }
        }
        public void ParseFirstProjectLineWhereProjectNameHasSpecialCharacters()
        {
            SolutionFile p = new SolutionFile();
            p.FullPath = "c:\\foo.sln";
            ProjectInSolution proj = new ProjectInSolution(p);

            p.ParseFirstProjectLine
            (
                "Project(\"{Project GUID}\")  = \"MyProject,(=IsGreat)\",  \"Relative path to project file\"    , \"Unique name-GUID\"",
                 proj
            );
            Assert.AreEqual(SolutionProjectType.Unknown, proj.ProjectType);
            Assert.AreEqual("MyProject,(=IsGreat)", proj.ProjectName);
            Assert.AreEqual("Relative path to project file", proj.RelativePath);
            Assert.AreEqual("Unique name-GUID", proj.ProjectGuid);
        }
Exemple #16
0
        internal ProjectInSolution(SolutionFile solution)
        {
            _projectType = SolutionProjectType.Unknown;
            _projectName = null;
            _relativePath = null;
            _projectGuid = null;
            _dependencies = new List<string>();
            _projectReferences = new ArrayList();
            _parentProjectGuid = null;
            _uniqueProjectName = null;
            _parentSolution = solution;

            // default to .NET Framework 3.5 if this is an old solution that doesn't explicitly say.
            _targetFrameworkMoniker = ".NETFramework,Version=v3.5";

            // This hashtable stores a AspNetCompilerParameters struct for each configuration name supported.
            _aspNetConfigurations = new Hashtable(StringComparer.OrdinalIgnoreCase);

            _projectConfigurations = new Dictionary<string, ProjectConfigurationInSolution>(StringComparer.OrdinalIgnoreCase);
        }
        public void ParseFirstProjectLine_InvalidProject()
        {
            SolutionFile p = new SolutionFile();
            p.FullPath = "c:\\foo.sln";
            ProjectInSolution proj = new ProjectInSolution(p);

            p.ParseFirstProjectLine
            (
                "Project(\"{Project GUID}\") = \"\", \"src\\.proj\", \"Unique name-GUID\"",
                 proj
            );
            Assert.AreEqual(SolutionProjectType.Unknown, proj.ProjectType);
            Assert.IsTrue(proj.ProjectName.StartsWith("EmptyProjectName"));
            Assert.AreEqual("src\\.proj", proj.RelativePath);
            Assert.AreEqual("Unique name-GUID", proj.ProjectGuid);
        }
        public void SolutionConfigurationWithDependenciesRelaysItsOutputs()
        {
            #region Large strings representing solution & projects
            const string solutionFileContents =
                @"
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 11
Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `B`, `B.csproj`, `{881C1674-4ECA-451D-85B6-D7C59B7F16FA}`
	ProjectSection(ProjectDependencies) = postProject
		{4A727FF8-65F2-401E-95AD-7C8BBFBE3167} = {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}
	EndProjectSection
EndProject
Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `C`, `C.csproj`, `{4A727FF8-65F2-401E-95AD-7C8BBFBE3167}`
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
		Release|Any CPU = Release|Any CPU
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = preSolution
		{4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Release|Any CPU.Build.0 = Release|Any CPU
		{881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
		{881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|Any CPU.Build.0 = Release|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
EndGlobal
";
            const string projectBravoFileContents =
                    @"
                        <Project ToolsVersion='msbuilddefaulttoolsversion' DefaultTargets='Build' xmlns='msbuildnamespace'>
                            <Target Name='Build' Outputs='@(ComputedQuestion)'>
                                <ItemGroup>
                                    <ComputedQuestion Include='What do you get if you multiply six by nine' />
                                </ItemGroup>
                            </Target>
                        </Project>
                    ";
            const string projectCharlieFileContents =
                    @"
                        <Project ToolsVersion='msbuilddefaulttoolsversion' DefaultTargets='Build' xmlns='msbuildnamespace'>
                            <Target Name='Build' Outputs='@(ComputedAnswer)'>
                                <ItemGroup>
                                    <ComputedAnswer Include='42' />
                                </ItemGroup>
                            </Target>
                        </Project>
                    ";
            const string automaticProjectFileContents = @"
<Project ToolsVersion='msbuilddefaulttoolsversion' DefaultTargets='compile' xmlns='msbuildnamespace'>
	<Target Name='compile'>
		<MSBuild Projects='B.csproj' Targets='Build'>
			<Output
				TaskParameter='TargetOutputs'
				ItemName='BravoProjectOutputs' />
		</MSBuild>
		<Message Importance='high' Text='BravoProjectOutputs: @(BravoProjectOutputs)' />
		<MSBuild Projects='C.csproj' Targets='Build'>
			<Output
				TaskParameter='TargetOutputs'
				ItemName='CharlieProjectOutputs' />
		</MSBuild>
		<Message Importance='high' Text='CharlieProjectOutputs: @(CharlieProjectOutputs)' />
		<MSBuild Projects='B.csproj.metaproj' Targets='Build'>
			<Output
				TaskParameter='TargetOutputs'
				ItemName='BravoMetaProjectOutputs' />
		</MSBuild>
		<Message Importance='high' Text='BravoMetaProjectOutputs: @(BravoMetaProjectOutputs)' />
		<Error Condition=` '@(CharlieProjectOutputs);@(BravoProjectOutputs)' != '@(BravoMetaProjectOutputs)' ` Text='Metaproj must relay outputs' />
	</Target>
</Project>";
            #endregion
            // arrange
            var logger = new MockLogger();
            var loggers = new List<ILogger>(1) {logger};
            var solutionFile = ObjectModelHelpers.CreateFileInTempProjectDirectory("MSBuildIssue.sln", solutionFileContents);
            ObjectModelHelpers.CreateFileInTempProjectDirectory("B.csproj", projectBravoFileContents);
            ObjectModelHelpers.CreateFileInTempProjectDirectory("C.csproj", projectCharlieFileContents);
            var solution = new SolutionFile {FullPath = solutionFile};
            solution.ParseSolutionFile();

            // act
            var instances = SolutionProjectGenerator.Generate(solution, null, null, new BuildEventContext(0, 0, 0, 0), null);

            // assert
            var projectBravoMetaProject = instances[1];
            Assert.IsFalse(projectBravoMetaProject.Targets.Any(kvp => kvp.Value.Outputs.Equals("@()")), "The outputItem parameter can be null; the Target element should not have an Outputs attribute in that case.");
            // saves the in-memory metaproj to disk
            projectBravoMetaProject.ToProjectRootElement().Save(projectBravoMetaProject.FullPath);
            var automaticProjectFile = ObjectModelHelpers.CreateFileInTempProjectDirectory("automatic.msbuild", automaticProjectFileContents);
            var automaticProject = new Project(automaticProjectFile);
            var buildResult = automaticProject.Build(loggers);
            Assert.AreEqual(true, buildResult, String.Join(Environment.NewLine, logger.Errors.Select(beea => beea.Message)));
        }
Exemple #19
0
        /// <summary>
        /// This method takes a path to a solution file, parses the projects and project dependencies
        /// in the solution file, and creates internal data structures representing the projects within
        /// the SLN.
        /// </summary>
        public static SolutionFile Parse(string solutionFile)
        {
            SolutionFile parser = new SolutionFile();
            parser.FullPath = solutionFile;

            parser.ParseSolutionFile();

            return parser;
        }
 IEnumerable<String> GetAllProjects(SolutionFile solution)
 {
   return solution.ProjectsByGuid.Keys.Cast<String>();
 }
        /// <summary>
        /// Adds a new property group with contents of the given solution configuration to the project
        /// Internal for unit-testing.
        /// </summary>
        internal static void AddPropertyGroupForSolutionConfiguration(ProjectRootElement msbuildProject, SolutionFile solutionFile, SolutionConfigurationInSolution solutionConfiguration)
        {
            ProjectPropertyGroupElement solutionConfigurationProperties = msbuildProject.CreatePropertyGroupElement();
            msbuildProject.AppendChild(solutionConfigurationProperties);
            solutionConfigurationProperties.Condition = GetConditionStringForConfiguration(solutionConfiguration);

            StringBuilder solutionConfigurationContents = new StringBuilder(1024);
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.OmitXmlDeclaration = true;
            using (XmlWriter xw = XmlWriter.Create(solutionConfigurationContents, settings))
            {
                xw.WriteStartElement("SolutionConfiguration");

                // add a project configuration entry for each project in the solution
                foreach (ProjectInSolution project in solutionFile.ProjectsInOrder)
                {
                    ProjectConfigurationInSolution projectConfiguration = null;

                    if (project.ProjectConfigurations.TryGetValue(solutionConfiguration.FullName, out projectConfiguration))
                    {
                        xw.WriteStartElement("ProjectConfiguration");
                        xw.WriteAttributeString("Project", project.ProjectGuid);
                        xw.WriteAttributeString("AbsolutePath", project.AbsolutePath);
                        xw.WriteAttributeString("BuildProjectInSolution", projectConfiguration.IncludeInBuild.ToString());
                        xw.WriteString(projectConfiguration.FullName);

                        foreach (string dependencyProjectGuid in project.Dependencies)
                        {
                            // This is a project that the current project depends *ON* (ie., it must build first)
                            ProjectInSolution dependencyProject;
                            if (!solutionFile.ProjectsByGuid.TryGetValue(dependencyProjectGuid, out dependencyProject))
                            {
                                // If it's not itself part of the solution, that's an invalid solution
                                ProjectFileErrorUtilities.VerifyThrowInvalidProjectFile(dependencyProject != null, "SubCategoryForSolutionParsingErrors", new BuildEventFileInfo(solutionFile.FullPath), "SolutionParseProjectDepNotFoundError", project.ProjectGuid, dependencyProjectGuid);
                            }

                            // Add it to the list of dependencies, but only if it should build in this solution configuration 
                            // (If a project is not selected for build in the solution configuration, it won't build even if it's depended on by something that IS selected for build)
                            // .. and only if it's known to be MSBuild format, as projects can't use the information otherwise 
                            if (dependencyProject.ProjectType == SolutionProjectType.KnownToBeMSBuildFormat)
                            {
                                ProjectConfigurationInSolution dependencyProjectConfiguration = null;
                                if (dependencyProject.ProjectConfigurations.TryGetValue(solutionConfiguration.FullName, out dependencyProjectConfiguration) &&
                                    WouldProjectBuild(solutionFile, solutionConfiguration.FullName, dependencyProject, dependencyProjectConfiguration))
                                {
                                    xw.WriteStartElement("ProjectDependency");
                                    xw.WriteAttributeString("Project", dependencyProjectGuid);
                                    xw.WriteEndElement();
                                }
                            }
                        }

                        xw.WriteEndElement(); // </ProjectConfiguration>
                    }
                }

                xw.WriteEndElement(); // </SolutionConfiguration>
            }

            var escapedSolutionConfigurationContents = EscapingUtilities.Escape(solutionConfigurationContents.ToString());

            solutionConfigurationProperties.AddProperty("CurrentSolutionConfigurationContents", escapedSolutionConfigurationContents);

            msbuildProject.AddItem(
                "SolutionConfiguration",
                solutionConfiguration.FullName,
                new Dictionary<string, string>
                {
                    { "Configuration", solutionConfiguration.ConfigurationName },
                    { "Platform", solutionConfiguration.PlatformName },
                    { "Content", escapedSolutionConfigurationContents },
                });
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 private SolutionProjectGenerator
     (
     SolutionFile solution,
     IDictionary<string, string> globalProperties,
     string toolsVersionOverride,
     BuildEventContext projectBuildEventContext,
     ILoggingService loggingService
     )
 {
     _solutionFile = solution;
     _globalProperties = globalProperties ?? new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
     _toolsVersionOverride = toolsVersionOverride;
     _projectBuildEventContext = projectBuildEventContext;
     _loggingService = loggingService;
 }
        /// <summary>
        /// To convert project-to-project references correctly, we need some data
        /// out of the solution file.  If we weren't given a solution file, then
        /// we search the project's directory and every parent directory all the
        /// way up to the root for the corresponding SLN file.
        /// </summary>
        /// <owner>RGoel</owner>
        private void SearchForSolutionFile
            (
            )
        {
            error.VerifyThrow(this.solutionFile == null, "Solution file already passed in!");
            error.VerifyThrow(this.projectGuid != null, "Need project Guid to find solution file.");

            // Start by looking for a solution file in the directory of the original project file.
            DirectoryInfo searchDirectory = new DirectoryInfo(Path.GetDirectoryName(Path.GetFullPath(this.oldProjectFile)));

            while (searchDirectory != null)
            {
                // Get a list of all the .SLN files in the current search directory.
                FileInfo[] slnFiles = searchDirectory.GetFiles("*.sln");

                // Open each .SLN file and parse it.  We're searching for a .SLN
                // file that contains the current project that we're converting.
                foreach (FileInfo slnFile in slnFiles)
                {
                    // Check that the extension really is ".SLN", because the above call to
                    // GetFiles will also return files such as blah.SLN1 and bloo.SLN2.
                    if (0 == String.Compare(".sln", slnFile.Extension, StringComparison.OrdinalIgnoreCase))
                    {
                        // Parse the .SLN file.
                        SolutionFile solutionParser = new SolutionFile();
                        solutionParser.FullPath = slnFile.FullName;

                        try
                        {
                            solutionParser.ParseSolutionFile();
                            this.conversionWarnings.AddRange(solutionParser.SolutionParserWarnings);

                            // Determine if our current project guid (for the project we're converting)
                            // is listed in the .SLN file.
                            if (solutionParser.GetProjectUniqueNameByGuid(this.projectGuid) != null)
                            {
                                // If we found our project listed, then this is the solution we will
                                // use to help us convert the project-to-project references.
                                this.solutionFile = slnFile.FullName;
                                this.solution = solutionParser;
                                return;
                            }
                        }
                        catch (InvalidProjectFileException)
                        {
                            // If the SLN wasn't valid, that's fine ... just skip it, and
                            // move on to the next one.
                        }
                    }
                }

                // Go up one directory, and search there.  Stop when we hit the root.
                searchDirectory = searchDirectory.Parent;
            }

            // If we don't find a solution file that contains our project, that's okay...
            // we can still proceed.  It just means that the converted project-to-project
            // references won't have the relative path to the referenced project.  This
            // may prevent command-line builds from being fully functional, but it's
            // not the end of the world.
        }
Exemple #24
0
        /// <summary>
        /// Helper method to create a SolutionFile object, and call it to parse the SLN file
        /// represented by the string contents passed in.
        /// </summary>
        /// <param name="solutionFileContents"></param>
        /// <returns></returns>
        static internal SolutionFile ParseSolutionHelper
            (
            string solutionFileContents
            )
        {
            solutionFileContents = solutionFileContents.Replace('\'', '"');
            StreamReader sr = StreamHelpers.StringToStreamReader(solutionFileContents);

            SolutionFile sp = new SolutionFile();
            sp.SolutionFileDirectory = Path.GetTempPath();
            sp.SolutionReader = sr;
            string tmpFileName = FileUtilities.GetTemporaryFile();
            sp.FullPath = tmpFileName + ".sln";
            // This file is not expected to exist at this point, so make sure it doesn't
            File.Delete(sp.FullPath);
            sp.ParseSolution();
            // Clean up the temporary file that got created with this call
            File.Delete(tmpFileName);
            return sp;
        }
Exemple #25
0
        /// <summary>
        /// Open a solution file and all referenced projects.
        /// </summary>
        public async Task <Solution> OpenSolutionAsync(string solutionFilePath, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (solutionFilePath == null)
            {
                throw new ArgumentNullException(nameof(solutionFilePath));
            }

            this.ClearSolution();

            var absoluteSolutionPath = this.GetAbsoluteSolutionPath(solutionFilePath, Directory.GetCurrentDirectory());

            using (_dataGuard.DisposableWait(cancellationToken))
            {
                this.SetSolutionProperties(absoluteSolutionPath);
            }

            VersionStamp version = default(VersionStamp);

#if !MSBUILD12
            Microsoft.Build.Construction.SolutionFile solutionFile = Microsoft.Build.Construction.SolutionFile.Parse(absoluteSolutionPath);
            var reportMode      = this.SkipUnrecognizedProjects ? ReportMode.Log : ReportMode.Throw;
            var invalidProjects = new List <ProjectInSolution>();

            // seed loaders from known project types
            using (_dataGuard.DisposableWait(cancellationToken))
            {
                foreach (var project in solutionFile.ProjectsInOrder)
                {
                    if (project.ProjectType == SolutionProjectType.SolutionFolder)
                    {
                        continue;
                    }

                    var projectAbsolutePath = TryGetAbsolutePath(project.AbsolutePath, reportMode);
                    if (projectAbsolutePath != null)
                    {
                        var extension = Path.GetExtension(projectAbsolutePath);
                        if (extension.Length > 0 && extension[0] == '.')
                        {
                            extension = extension.Substring(1);
                        }

                        var loader = ProjectFileLoader.GetLoaderForProjectFileExtension(this, extension);
                        if (loader != null)
                        {
                            _projectPathToLoaderMap[projectAbsolutePath] = loader;
                        }
                    }
                    else
                    {
                        invalidProjects.Add(project);
                    }
                }
            }

            // a list to accumulate all the loaded projects
            var loadedProjects = new List <ProjectInfo>();

            // load all the projects
            foreach (var project in solutionFile.ProjectsInOrder)
            {
                cancellationToken.ThrowIfCancellationRequested();

                if (project.ProjectType != SolutionProjectType.SolutionFolder && !invalidProjects.Contains(project))
                {
                    var projectAbsolutePath = TryGetAbsolutePath(project.AbsolutePath, reportMode);
                    if (projectAbsolutePath != null)
                    {
                        IProjectFileLoader loader;
                        if (TryGetLoaderFromProjectPath(projectAbsolutePath, reportMode, out loader))
                        {
                            // projects get added to 'loadedProjects' as side-effect
                            // never perfer metadata when loading solution, all projects get loaded if they can.
                            var tmp = await GetOrLoadProjectAsync(projectAbsolutePath, loader, preferMetadata : false, loadedProjects : loadedProjects, cancellationToken : cancellationToken).ConfigureAwait(false);
                        }
                    }
                }
            }
#else
            SolutionFile solutionFile = null;

            using (var reader = new StreamReader(absoluteSolutionPath))
            {
                version = VersionStamp.Create(File.GetLastWriteTimeUtc(absoluteSolutionPath));
                var text = await reader.ReadToEndAsync().ConfigureAwait(false);

                solutionFile = SolutionFile.Parse(new StringReader(text));
            }

            var solutionFolder = Path.GetDirectoryName(absoluteSolutionPath);

            // seed loaders from known project types
            using (_dataGuard.DisposableWait())
            {
                foreach (var projectBlock in solutionFile.ProjectBlocks)
                {
                    string absoluteProjectPath;
                    if (TryGetAbsoluteProjectPath(projectBlock.ProjectPath, solutionFolder, ReportMode.Ignore, out absoluteProjectPath))
                    {
                        var loader = ProjectFileLoader.GetLoaderForProjectTypeGuid(this, projectBlock.ProjectTypeGuid);
                        if (loader != null)
                        {
                            _projectPathToLoaderMap[absoluteProjectPath] = loader;
                        }
                    }
                }
            }

            // a list to accumulate all the loaded projects
            var loadedProjects = new List <ProjectInfo>();

            var reportMode = this.SkipUnrecognizedProjects ? ReportMode.Log : ReportMode.Throw;

            // load all the projects
            foreach (var projectBlock in solutionFile.ProjectBlocks)
            {
                cancellationToken.ThrowIfCancellationRequested();

                string absoluteProjectPath;
                if (TryGetAbsoluteProjectPath(projectBlock.ProjectPath, solutionFolder, reportMode, out absoluteProjectPath))
                {
                    IProjectFileLoader loader;
                    if (TryGetLoaderFromProjectPath(absoluteProjectPath, reportMode, out loader))
                    {
                        // projects get added to 'loadedProjects' as side-effect
                        // never perfer metadata when loading solution, all projects get loaded if they can.
                        var tmp = await GetOrLoadProjectAsync(absoluteProjectPath, loader, preferMetadata : false, loadedProjects : loadedProjects, cancellationToken : cancellationToken).ConfigureAwait(false);
                    }
                }
            }
#endif

            // construct workspace from loaded project infos
            this.OnSolutionAdded(SolutionInfo.Create(SolutionId.CreateNewId(debugName: absoluteSolutionPath), version, absoluteSolutionPath, loadedProjects));

            this.UpdateReferencesAfterAdd();

            return(this.CurrentSolution);
        }
        /// <summary>
        /// Helper method to create a SolutionFile object, and call it to parse the SLN file
        /// represented by the string contents passed in.
        /// </summary>
        /// <param name="solutionFileContents"></param>
        /// <returns></returns>
        static internal SolutionFile ParseSolutionHelper(string solutionFileContents)
        {
            solutionFileContents = solutionFileContents.Replace('\'', '"');
            StreamReader sr = StreamHelpers.StringToStreamReader(solutionFileContents);

            SolutionFile sp = new SolutionFile();
            sp.SolutionFileDirectory = Path.GetTempPath();
            sp.SolutionReader = sr;
            sp.FullPath = FileUtilities.GetTemporaryFileName(".sln");
            sp.ParseSolution();
            // Clean up the temporary file that got created with this call
            return sp;
        }
        /// <summary>
        /// Figure out what solution configuration we are going to build, whether or not it actually exists in the solution
        /// file.
        /// </summary>
        private static string DetermineLikelyActiveSolutionConfiguration(SolutionFile solutionFile, IDictionary<string, string> globalProperties)
        {
            string activeSolutionConfiguration = null;
            string activeSolutionPlatform = null;

            globalProperties.TryGetValue("Configuration", out activeSolutionConfiguration);
            globalProperties.TryGetValue("Platform", out activeSolutionPlatform);

            if (String.IsNullOrEmpty(activeSolutionConfiguration))
            {
                activeSolutionConfiguration = solutionFile.GetDefaultConfigurationName();
            }

            if (String.IsNullOrEmpty(activeSolutionPlatform))
            {
                activeSolutionPlatform = solutionFile.GetDefaultPlatformName();
            }

            SolutionConfigurationInSolution configurationInSolution = new SolutionConfigurationInSolution(activeSolutionConfiguration, activeSolutionPlatform);

            return configurationInSolution.FullName;
        }
        /// <summary>
        /// Initialize all member variables to get ready for a conversion.
        /// </summary>
        /// <owner>RGoel</owner>
        private void Initialize()
        {
            this.xmakeProject = null;
            this.globalPropertyGroup = null;
            this.language = null;
            this.projectGuid = null;
            this.preBuildEvent = null;
            this.postBuildEvent = null;
            this.solution = null;
            this.newWebReferencePropertiesAdded = false;
            this.platformForVSD = null;
            this.assemblyName = null;
            this.outputType = null;
            this.hasWindowsFormsReference = false;
            this.isMyTypeAlreadySetInOriginalProject = false;
            this.conversionWarnings = new ArrayList();

            this.propertiesToEscape = new Dictionary<string,string>(StringComparer.OrdinalIgnoreCase);
            this.propertiesToEscape.Add("ApplicationIcon", null);
            this.propertiesToEscape.Add("AssemblyKeyContainerName", null);
            this.propertiesToEscape.Add("AssemblyName", null);
            this.propertiesToEscape.Add("AssemblyOriginatorKeyFile", null);
            this.propertiesToEscape.Add("RootNamespace", null);
            this.propertiesToEscape.Add("StartupObject", null);
            this.propertiesToEscape.Add("ConfigurationOverrideFile", null);
            this.propertiesToEscape.Add("DocumentationFile", null);
            this.propertiesToEscape.Add("OutputPath", null);
        }
        public void SolutionConfigurationWithDependenciesRelaysItsOutputs()
        {
            #region Large strings representing solution & projects
            const string solutionFileContents =
                @"
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 11
Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `B`, `B.csproj`, `{881C1674-4ECA-451D-85B6-D7C59B7F16FA}`
	ProjectSection(ProjectDependencies) = postProject
		{4A727FF8-65F2-401E-95AD-7C8BBFBE3167} = {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}
	EndProjectSection
EndProject
Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `C`, `C.csproj`, `{4A727FF8-65F2-401E-95AD-7C8BBFBE3167}`
EndProject
Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `D`, `D.csproj`, `{B6E7E06F-FC0B-48F1-911A-55E0E1566F00}`
EndProject
Global
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
		Debug|Any CPU = Debug|Any CPU
	EndGlobalSection
	GlobalSection(ProjectConfigurationPlatforms) = preSolution
		{4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
		{B6E7E06F-FC0B-48F1-911A-55E0E1566F00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		{B6E7E06F-FC0B-48F1-911A-55E0E1566F00}.Debug|Any CPU.Build.0 = Debug|Any CPU
	EndGlobalSection
	GlobalSection(SolutionProperties) = preSolution
		HideSolutionNode = FALSE
	EndGlobalSection
EndGlobal
";
            const string projectBravoFileContents =
                    @"
                        <Project ToolsVersion='msbuilddefaulttoolsversion' DefaultTargets='Build' xmlns='msbuildnamespace'>
                            <Target Name='Build' Outputs='@(ComputedQuestion)'>
                                <ItemGroup>
                                    <ComputedQuestion Include='What do you get if you multiply six by nine' />
                                </ItemGroup>
                            </Target>
                            <ItemGroup>
                                <ProjectReference Include='D.csproj'>
                                    <Project>{B6E7E06F-FC0B-48F1-911A-55E0E1566F00}</Project>
                                    <Name>D</Name>
                                </ProjectReference>
                            </ItemGroup>
                        </Project>
                    ";
            const string projectCharlieFileContents =
                    @"
                        <Project ToolsVersion='msbuilddefaulttoolsversion' DefaultTargets='Build' xmlns='msbuildnamespace'>
                            <Target Name='Build' Outputs='@(ComputedAnswer)'>
                                <ItemGroup>
                                    <ComputedAnswer Include='42' />
                                </ItemGroup>
                            </Target>
                        </Project>
                    ";
            const string projectDeltaFileContents =
                    @"
                        <Project ToolsVersion='msbuilddefaulttoolsversion' DefaultTargets='Build' xmlns='msbuildnamespace'>
                            <PropertyGroup>
                                <ProjectGuid>{B6E7E06F-FC0B-48F1-911A-55E0E1566F00}</ProjectGuid>
                            </PropertyGroup>
                            <Target Name='Build' Outputs='@(ComputedPunctuation)'>
                                <ItemGroup>
                                    <ComputedPunctuation Include='!!!' />
                                </ItemGroup>
                            </Target>
                        </Project>
                    ";
            const string automaticProjectFileContents = @"
<Project ToolsVersion='msbuilddefaulttoolsversion' DefaultTargets='compile' xmlns='msbuildnamespace'>
    <Target Name='compile'>
        <!-- Build projects to get a baseline for their output -->
        <MSBuild Projects='B.csproj' Targets='Build'>
            <Output
                TaskParameter='TargetOutputs'
                ItemName='BravoProjectOutputs' />
        </MSBuild>
        <Message Importance='high' Text='BravoProjectOutputs: @(BravoProjectOutputs)' />

        <MSBuild Projects='C.csproj' Targets='Build'>
            <Output
                TaskParameter='TargetOutputs'
                ItemName='CharlieProjectOutputs' />
        </MSBuild>
        <Message Importance='high' Text='CharlieProjectOutputs: @(CharlieProjectOutputs)' />

        <MSBuild Projects='D.csproj' Targets='Build'>
            <Output
                TaskParameter='TargetOutputs'
                ItemName='DeltaProjectOutputs' />
        </MSBuild>
        <Message Importance='high' Text='DeltaProjectOutputs: @(DeltaProjectOutputs)' />

        <PropertyGroup>
            <StringifiedBravoProjectOutputs>@(BravoProjectOutputs)</StringifiedBravoProjectOutputs>
            <StringifiedCharlieProjectOutputs>@(CharlieProjectOutputs)</StringifiedCharlieProjectOutputs>
            <StringifiedDeltaProjectOutputs>@(DeltaProjectOutputs)</StringifiedDeltaProjectOutputs>
        </PropertyGroup>

        <!-- Explicitly build the metaproject generated for B -->
        <MSBuild Projects='B.csproj.metaproj' Targets='Build'>
            <Output
                TaskParameter='TargetOutputs'
                ItemName='BravoMetaProjectOutputs' />
        </MSBuild>
        <Message Importance='high' Text='BravoMetaProjectOutputs: @(BravoMetaProjectOutputs)' />
        <Error Condition=` '@(BravoProjectOutputs)' != '@(BravoMetaProjectOutputs)' ` Text='Metaproj outputs must match outputs of normal project build.' />

        <!-- Build the solution as a whole (which will build the metaproj and return overall outputs) -->
        <MSBuild Projects='MSBuildIssue.sln'>
            <Output
                TaskParameter='TargetOutputs'
                ItemName='SolutionProjectOutputs' />
        </MSBuild>
        <Message Importance='high' Text='SolutionProjectOutputs: @(SolutionProjectOutputs)' />
        <Error Condition=` '@(SolutionProjectOutputs->Count())' != '3' ` Text='Overall sln outputs must include outputs of each referenced project (there should be 3).' />
        <Error Condition=` '@(SolutionProjectOutputs->AnyHaveMetadataValue('Identity', '$(StringifiedBravoProjectOutputs)'))' != 'true'` Text='Overall sln outputs must include outputs of normal project build of project B.' />
        <Error Condition=` '@(SolutionProjectOutputs->AnyHaveMetadataValue('Identity', '$(StringifiedCharlieProjectOutputs)'))' != 'true' ` Text='Overall sln outputs must include outputs of normal project build of project C.' />
        <Error Condition=` '@(SolutionProjectOutputs->AnyHaveMetadataValue('Identity', '$(StringifiedDeltaProjectOutputs)'))' != 'true' ` Text='Overall sln outputs must include outputs of normal project build of project D.' />
    </Target>
</Project>";
            #endregion

            var logger = new MockLogger();
            var loggers = new List<ILogger>(1) { logger };
            var solutionFile = ObjectModelHelpers.CreateFileInTempProjectDirectory("MSBuildIssue.sln", solutionFileContents);
            ObjectModelHelpers.CreateFileInTempProjectDirectory("B.csproj", projectBravoFileContents);
            ObjectModelHelpers.CreateFileInTempProjectDirectory("C.csproj", projectCharlieFileContents);
            ObjectModelHelpers.CreateFileInTempProjectDirectory("D.csproj", projectDeltaFileContents);
            var solution = new SolutionFile { FullPath = solutionFile };
            solution.ParseSolutionFile();

            var instances = SolutionProjectGenerator.Generate(solution, null, null, new BuildEventContext(0, 0, 0, 0), null);

            var projectBravoMetaProject = instances[1];
            Assert.False(projectBravoMetaProject.Targets.Any(kvp => kvp.Value.Outputs.Equals("@()"))); // "The outputItem parameter can be null; the Target element should not have an Outputs attribute in that case."
            // saves the in-memory metaproj to disk
            projectBravoMetaProject.ToProjectRootElement().Save(projectBravoMetaProject.FullPath);
            var automaticProjectFile = ObjectModelHelpers.CreateFileInTempProjectDirectory("automatic.msbuild", automaticProjectFileContents);
            var automaticProject = new Project(automaticProjectFile);
            var buildResult = automaticProject.Build(loggers);

            // NOTE: most of the actual assertions for this test are embedded in automaticProjectFileContents as <Error>s
            Assert.True(buildResult, String.Join(Environment.NewLine, logger.Errors.Select(beea => beea.Message)));
        }
        /// <summary>
        /// This method generates an MSBuild project file from the list of projects and project dependencies 
        /// that have been collected from the solution file.
        /// </summary>
        /// <param name="solution">The parser which contains the solution file.</param>
        /// <param name="globalProperties">The global properties.</param>
        /// <param name="toolsVersionOverride">Tools Version override (may be null).  This should be any tools version explicitly passed to the command-line or from an MSBuild ToolsVersion parameter.</param>
        /// <param name="projectBuildEventContext">The logging context for this project.</param>
        /// <param name="loggingService">The logging service.</param>
        /// <returns>An array of ProjectInstances.  The first instance is the traversal project, the remaining are the metaprojects for each project referenced in the solution.</returns>
        internal static ProjectInstance[] Generate
            (
            SolutionFile solution,
            IDictionary<string, string> globalProperties,
            string toolsVersionOverride,
            BuildEventContext projectBuildEventContext,
            ILoggingService loggingService
            )
        {
            SolutionProjectGenerator projectGenerator = new SolutionProjectGenerator
                (
                solution,
                globalProperties,
                toolsVersionOverride,
                projectBuildEventContext,
                loggingService
                );

            return projectGenerator.Generate();
        }
        /// <summary>
        /// Convert passed in solution file to an MSBuild project. This method is used by Sln2Proj
        /// </summary>
        public bool ConvertSLN2Proj(string nameSolutionFile)
        {
            // Set the environment variable to cause the SolutionProjectGenerator to emit the project to disk
            string oldValueForMSBuildEmitSolution = Environment.GetEnvironmentVariable("MSBuildEmitSolution");
            Environment.SetEnvironmentVariable("MSBuildEmitSolution", "1");

            if (nameSolutionFile == null || !File.Exists(nameSolutionFile))
            {
                return false;
            }

            // Parse the solution
            SolutionFile solution = new SolutionFile();
            solution.FullPath = nameSolutionFile;
            solution.ParseSolutionFile();

            // Generate the in-memory MSBuild project and output it to disk
            ProjectInstance[] instance = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, null);


            //Reset the environment variable
            Environment.SetEnvironmentVariable("MSBuildEmitSolution", oldValueForMSBuildEmitSolution);

            return true;
        }
        /// <summary>
        /// Normally the active solution configuration/platform is determined when we build the solution
        /// wrapper project, not when we create it. However, we need to know them to scan project references
        /// for the right project configuration/platform. It's unlikely that references would be conditional, 
        /// but still possible and we want to get that case right.
        /// </summary>
        internal static string PredictActiveSolutionConfigurationName(SolutionFile solutionFile, IDictionary<string, string> globalProperties)
        {
            string candidateFullSolutionConfigurationName = DetermineLikelyActiveSolutionConfiguration(solutionFile, globalProperties);

            // Now check if this solution configuration actually exists
            string fullSolutionConfigurationName = null;

            foreach (SolutionConfigurationInSolution solutionConfiguration in solutionFile.SolutionConfigurations)
            {
                if (String.Equals(solutionConfiguration.FullName, candidateFullSolutionConfigurationName, StringComparison.OrdinalIgnoreCase))
                {
                    fullSolutionConfigurationName = solutionConfiguration.FullName;
                    break;
                }
            }

            return fullSolutionConfigurationName;
        }
        // Ignore: Changes to the current directory interfere with the toolset reader.
        public void SolutionPassesSubToolsetToChildProjects2()
        {
            string classLibraryContentsToolsV4 = ObjectModelHelpers.CleanupFileContents(
                    @"
                        <Project ToolsVersion=""4.0"" DefaultTargets=""Build"" xmlns='msbuildnamespace'>
                            <Target Name='Build'>
                                <Message Text='.[$(VisualStudioVersion)]. .[$(MSBuildToolsVersion)].' />
                            </Target>
                        </Project>
                    ");

            string classLibraryContentsToolsV12 = ObjectModelHelpers.CleanupFileContents(
                    @"
                        <Project ToolsVersion=""msbuilddefaulttoolsversion"" DefaultTargets=""Build"" xmlns='msbuildnamespace'>
                            <Target Name='Build'>
                                <Message Text='.[$(VisualStudioVersion)]. .[$(MSBuildToolsVersion)].' />
                            </Target>
                        </Project>
                    ");

            string solutionFilePreambleV11 =
                    @"
                        Microsoft Visual Studio Solution File, Format Version 12.00
                        # Visual Studio Dev11
                     ";

            string solutionFilePreambleV12 =
                    @"
                        Microsoft Visual Studio Solution File, Format Version 12.00
                        # Visual Studio Dev11
                        VisualStudioVersion = 12.0.20311.0 VSPRO_PLATFORM
                        MinimumVisualStudioVersion = 10.0.40219.1
                     ";

            string solutionBodySingleProjectContents =
                    @"

                        Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ClassLibrary1"", ""ClassLibrary1.csproj"", ""{6185CC21-BE89-448A-B3C0-D1C27112E595}""
                        EndProject
                        Global
                            GlobalSection(SolutionConfigurationPlatforms) = preSolution
                                Debug|Mixed Platforms = Debug|Mixed Platforms
                                Release|Any CPU = Release|Any CPU
                            EndGlobalSection
                            GlobalSection(ProjectConfigurationPlatforms) = postSolution
                                {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Mixed Platforms.ActiveCfg = CSConfig1|Any CPU
                                {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Mixed Platforms.Build.0 = CSConfig1|Any CPU
                                {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.ActiveCfg = CSConfig2|Any CPU
                            EndGlobalSection
                        EndGlobal
                    ";

            string solutionBodyMultipleProjectsContents =
                @"
                    Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ClassLibrary1"", ""ClassLibrary1.csproj"", ""{A437DBE9-DCAA-46D8-9D80-A50EDB2244FD}""
                    EndProject
                    Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ClassLibrary2"", ""ClassLibrary2.csproj"", ""{84AA5584-4B0F-41DE-95AA-589E1447EDA0}""
                    EndProject
                    Global
	                    GlobalSection(SolutionConfigurationPlatforms) = preSolution
		                    Debug|Any CPU = Debug|Any CPU
		                    Release|Any CPU = Release|Any CPU
	                    EndGlobalSection
	                    GlobalSection(ProjectConfigurationPlatforms) = postSolution
		                    {A437DBE9-DCAA-46D8-9D80-A50EDB2244FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		                    {A437DBE9-DCAA-46D8-9D80-A50EDB2244FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
		                    {A437DBE9-DCAA-46D8-9D80-A50EDB2244FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
		                    {A437DBE9-DCAA-46D8-9D80-A50EDB2244FD}.Release|Any CPU.Build.0 = Release|Any CPU
		                    {84AA5584-4B0F-41DE-95AA-589E1447EDA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
		                    {84AA5584-4B0F-41DE-95AA-589E1447EDA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
		                    {84AA5584-4B0F-41DE-95AA-589E1447EDA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
		                    {84AA5584-4B0F-41DE-95AA-589E1447EDA0}.Release|Any CPU.Build.0 = Release|Any CPU
	                    EndGlobalSection
	                    GlobalSection(SolutionProperties) = preSolution
		                    HideSolutionNode = FALSE
	                    EndGlobalSection
                    EndGlobal
                ";


            string solutionFileContentsDev11 = solutionFilePreambleV11 + solutionBodySingleProjectContents;
            string solutionFileContentsDev12 = solutionFilePreambleV12 + solutionBodySingleProjectContents;

            string[] solutions = { solutionFileContentsDev11, solutionFileContentsDev12, solutionFileContentsDev12 };
            string[] projects = { classLibraryContentsToolsV4, classLibraryContentsToolsV4, classLibraryContentsToolsV12 };
            string[] logoutputs = { ".[11.0]. .[4.0].", ".[11.0]. .[4.0].", String.Format(".[{0}]. .[{0}].", ObjectModelHelpers.MSBuildDefaultToolsVersion) };

            string previousLegacyEnvironmentVariable = Environment.GetEnvironmentVariable("MSBUILDLEGACYDEFAULTTOOLSVERSION");

            try
            {
                Environment.SetEnvironmentVariable("MSBUILDLEGACYDEFAULTTOOLSVERSION", "1");
                InternalUtilities.RefreshInternalEnvironmentValues();

                for (int i = 0; i < solutions.Length; i++)
                {
                    string solutionFile = ObjectModelHelpers.CreateFileInTempProjectDirectory("Foo.sln", solutions[i]);
                    string projectFile = ObjectModelHelpers.CreateFileInTempProjectDirectory("ClassLibrary1.csproj", projects[i]);
                    SolutionFile sp = new SolutionFile();

                    sp.FullPath = solutionFile;
                    sp.ParseSolutionFile();

                    ProjectInstance[] instances = SolutionProjectGenerator.Generate(sp, null, null, new BuildEventContext(0, 0, 0, 0), null);

                    MockLogger logger = new MockLogger();
                    List<ILogger> loggers = new List<ILogger>(1);
                    loggers.Add(logger);

                    instances[0].Build(loggers);
                    logger.AssertLogContains(logoutputs[i]);
                }

                // Test Dev 12 sln and mixed v4.0 and v12.0 projects
                string solutionFileContentsDev12MultipleProjects = solutionFilePreambleV12 + solutionBodyMultipleProjectsContents;

                string solutionFileMultipleProjects = ObjectModelHelpers.CreateFileInTempProjectDirectory("Foo.sln", solutionFileContentsDev12MultipleProjects);
                string projectFileV4 = ObjectModelHelpers.CreateFileInTempProjectDirectory("ClassLibrary1.csproj", classLibraryContentsToolsV4);
                string projectFileV12 = ObjectModelHelpers.CreateFileInTempProjectDirectory("ClassLibrary2.csproj", classLibraryContentsToolsV12);

                SolutionFile sp1 = new SolutionFile();

                sp1.FullPath = solutionFileMultipleProjects;
                sp1.ParseSolutionFile();
                ProjectInstance[] instances1 = SolutionProjectGenerator.Generate(sp1, null, null, new BuildEventContext(0, 0, 0, 0), null);

                MockLogger logger1 = new MockLogger();
                List<ILogger> loggers1 = new List<ILogger>(1);
                loggers1.Add(logger1);

                instances1[0].Build(loggers1);
                logger1.AssertLogContains(".[11.0]. .[4.0].");
                logger1.AssertLogContains(String.Format(".[{0}]. .[{0}].", ObjectModelHelpers.MSBuildDefaultToolsVersion));
            }
            finally
            {
                Environment.SetEnvironmentVariable("MSBUILDLEGACYDEFAULTTOOLSVERSION", previousLegacyEnvironmentVariable);
                InternalUtilities.RefreshInternalEnvironmentValues();
            }
        }
        /// <summary>
        /// Returns true if the specified project will build in the currently selected solution configuration.
        /// </summary>
        private static bool WouldProjectBuild(SolutionFile solutionFile, string selectedSolutionConfiguration, ProjectInSolution project, ProjectConfigurationInSolution projectConfiguration)
        {
            if (projectConfiguration == null)
            {
                if (project.ProjectType == SolutionProjectType.WebProject)
                {
                    // Sometimes web projects won't have the configuration we need (Release typically.)  But they should still build if there is
                    // a solution configuration for it
                    foreach (SolutionConfigurationInSolution configuration in solutionFile.SolutionConfigurations)
                    {
                        if (String.Equals(configuration.FullName, selectedSolutionConfiguration, StringComparison.OrdinalIgnoreCase))
                        {
                            return true;
                        }
                    }
                }

                // No configuration, so it can't build.
                return false;
            }

            if (!projectConfiguration.IncludeInBuild)
            {
                // Not included in the build.
                return false;
            }

            return true;
        }
        // Ignore: Changes to the current directory interfere with the toolset reader.
        public void SolutionDoesntPassSubToolsetToChildProjects()
        {
            try
            {
                string classLibraryContents =
                    @"
                        <Project ToolsVersion=""4.0"" DefaultTargets=""Build"" xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
                            <Target Name='Build'>
                                <Message Text='.[$(VisualStudioVersion)].' />
                                <Message Text='.[[$(MSBuildToolsVersion)]].' />
                            </Target>
                        </Project>
                    ";

                string projectFile = ObjectModelHelpers.CreateFileInTempProjectDirectory("ClassLibrary1.csproj", classLibraryContents);

                string solutionFileContents =
                    @"
                        Microsoft Visual Studio Solution File, Format Version 12.00
                        # Visual Studio Dev11
                        Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ClassLibrary1"", ""ClassLibrary1.csproj"", ""{6185CC21-BE89-448A-B3C0-D1C27112E595}""
                        EndProject
                        Global
                            GlobalSection(SolutionConfigurationPlatforms) = preSolution
                                Debug|Mixed Platforms = Debug|Mixed Platforms
                                Release|Any CPU = Release|Any CPU
                            EndGlobalSection
                            GlobalSection(ProjectConfigurationPlatforms) = postSolution
                                {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Mixed Platforms.ActiveCfg = CSConfig1|Any CPU
                                {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Mixed Platforms.Build.0 = CSConfig1|Any CPU
                                {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.ActiveCfg = CSConfig2|Any CPU
                            EndGlobalSection
                        EndGlobal
                    ";

                string solutionFile = ObjectModelHelpers.CreateFileInTempProjectDirectory("Foo.sln", solutionFileContents);

                SolutionFile sp = new SolutionFile();

                sp.FullPath = solutionFile;
                sp.ParseSolutionFile();

                ProjectInstance[] instances = SolutionProjectGenerator.Generate(sp, null, null, new BuildEventContext(0, 0, 0, 0), null);

                Assert.AreEqual(ObjectModelHelpers.MSBuildDefaultToolsVersion, instances[0].ToolsVersion);
                Assert.AreEqual("11.0", instances[0].SubToolsetVersion);
                Assert.AreEqual("11.0", instances[0].GetPropertyValue("VisualStudioVersion"));

                MockLogger logger = new MockLogger();
                List<ILogger> loggers = new List<ILogger>(1);
                loggers.Add(logger);


                instances[0].Build(loggers);
                logger.AssertLogContains(String.Format(".[{0}].", ObjectModelHelpers.MSBuildDefaultToolsVersion));
            }
            finally
            {
                ObjectModelHelpers.DeleteTempProjectDirectory();
            }
        }