diff --git a/src/Build/Definition/ProjectCollection.cs b/src/Build/Definition/ProjectCollection.cs index 031e31f1e2e..a228be8f4e2 100644 --- a/src/Build/Definition/ProjectCollection.cs +++ b/src/Build/Definition/ProjectCollection.cs @@ -14,6 +14,7 @@ using Microsoft.Build.BackEnd.Logging; using Microsoft.Build.Collections; using Microsoft.Build.Construction; +using Microsoft.Build.Definition; using Microsoft.Build.Execution; using Microsoft.Build.Framework; using Microsoft.Build.Internal; @@ -1156,15 +1157,30 @@ public Project LoadProject(string fileName, string toolsVersion) /// The tools version. May be null. /// A loaded project. public Project LoadProject(string fileName, IDictionary globalProperties, string toolsVersion) + { + return LoadProjectWithOptions(fileName, new ProjectOptions { GlobalProperties = globalProperties, ToolsVersion = toolsVersion }); + } + + /// + /// Loads a project with the specified filename, tools version and global properties. + /// If a matching project is already loaded, it will be returned, otherwise a new project will be loaded. + /// + /// The project file to load + /// The to use. + /// A loaded project. + public Project LoadProjectWithOptions(string fileName, ProjectOptions projectOptions) { ErrorUtilities.VerifyThrowArgumentLength(fileName); fileName = FileUtilities.NormalizePath(fileName); using (_locker.EnterDisposableWriteLock()) { - if (globalProperties == null) + // We can only work on this Collection. + projectOptions.ProjectCollection = this; + + if (projectOptions.GlobalProperties == null) { - globalProperties = GlobalProperties; + projectOptions.GlobalProperties = GlobalProperties; } else { @@ -1174,9 +1190,9 @@ public Project LoadProject(string fileName, IDictionary globalPr // BUT remember that project global properties win -- don't override a property that already exists. foreach (KeyValuePair globalProperty in GlobalProperties) { - if (!globalProperties.ContainsKey(globalProperty.Key)) + if (!projectOptions.GlobalProperties.ContainsKey(globalProperty.Key)) { - globalProperties.Add(globalProperty); + projectOptions.GlobalProperties.Add(globalProperty); } } } @@ -1185,7 +1201,7 @@ public Project LoadProject(string fileName, IDictionary globalPr // passed a relative path, the caller assumes we will prepend the current directory. string toolsVersionFromProject = null; - if (toolsVersion == null) + if (projectOptions.ToolsVersion == null) { // Load the project XML to get any ToolsVersion attribute. // If there isn't already an equivalent project loaded, the real load we'll do will be satisfied from the cache. @@ -1194,7 +1210,7 @@ public Project LoadProject(string fileName, IDictionary globalPr // Either way, no time wasted. try { - ProjectRootElement xml = ProjectRootElement.OpenProjectOrSolution(fileName, globalProperties, toolsVersion, ProjectRootElementCache, true /*explicitlyloaded*/); + ProjectRootElement xml = ProjectRootElement.OpenProjectOrSolution(fileName, projectOptions.GlobalProperties, projectOptions.ToolsVersion, ProjectRootElementCache, true /*explicitlyloaded*/); toolsVersionFromProject = (xml.ToolsVersion.Length > 0) ? xml.ToolsVersion : DefaultToolsVersion; } catch (InvalidProjectFileException ex) @@ -1205,14 +1221,14 @@ public Project LoadProject(string fileName, IDictionary globalPr } } - string effectiveToolsVersion = Utilities.GenerateToolsVersionToUse(toolsVersion, toolsVersionFromProject, GetToolset, DefaultToolsVersion, out _); - Project project = _loadedProjects.GetMatchingProjectIfAny(fileName, globalProperties, effectiveToolsVersion); + string effectiveToolsVersion = Utilities.GenerateToolsVersionToUse(projectOptions.ToolsVersion, toolsVersionFromProject, GetToolset, DefaultToolsVersion, out _); + Project project = _loadedProjects.GetMatchingProjectIfAny(fileName, projectOptions.GlobalProperties, effectiveToolsVersion); if (project == null) { // The Project constructor adds itself to our collection, // it is not done by us - project = new Project(fileName, globalProperties, effectiveToolsVersion, this); + project = Project.FromFile(fileName, projectOptions); } return project;