/// <summary> /// Sets the given property in the given property group. /// </summary> private void SetProperty(ToolsetPropertyDefinition property, PropertyDictionary <ProjectPropertyInstance> propertyGroup, PropertyDictionary <ProjectPropertyInstance> globalProperties) { try { // Global properties cannot be overwritten if (globalProperties[property.Name] == null) { propertyGroup.Set(ProjectPropertyInstance.Create(property.Name, EscapingUtilities.UnescapeAll(property.Value), true /* may be reserved */, false /* not immutable */)); } } catch (ArgumentException ex) { InvalidToolsetDefinitionException.Throw(ex, "InvalidPropertyNameInToolset", property.Name, property.Source.LocationString, ex.Message); } }
/// <summary> /// Provides an enumerator over property definitions for a specified sub-toolset version /// under a specified toolset version. /// </summary> /// <param name="toolsVersion">The tools version.</param> /// <param name="subToolsetVersion">The sub-toolset version.</param> /// <returns>An enumeration of property definitions.</returns> protected override IEnumerable <ToolsetPropertyDefinition> GetSubToolsetPropertyDefinitions(string toolsVersion, string subToolsetVersion) { ErrorUtilities.VerifyThrowArgumentLength(subToolsetVersion, "subToolsetVersion"); RegistryKeyWrapper toolsVersionWrapper = null; RegistryKeyWrapper subToolsetWrapper = null; try { try { toolsVersionWrapper = _msbuildRegistryWrapper.OpenSubKey("ToolsVersions\\" + toolsVersion); } catch (RegistryException ex) { InvalidToolsetDefinitionException.Throw(ex, "RegistryReadError", ex.Source, ex.Message); } try { subToolsetWrapper = toolsVersionWrapper.OpenSubKey(subToolsetVersion); } catch (RegistryException ex) { InvalidToolsetDefinitionException.Throw(ex, "RegistryReadError", ex.Source, ex.Message); } foreach (string propertyName in subToolsetWrapper.GetValueNames()) { yield return(CreatePropertyFromRegistry(subToolsetWrapper, propertyName)); } } finally { if (toolsVersionWrapper != null) { toolsVersionWrapper.Dispose(); } if (subToolsetWrapper != null) { subToolsetWrapper.Dispose(); } } }
/// <summary> /// Provides an enumerator over property definitions for a specified tools version /// </summary> protected override IEnumerable <ToolsetPropertyDefinition> GetPropertyDefinitions(string toolsVersion) { ToolsetElement toolsetElement = ConfigurationSection.Toolsets.GetElement(toolsVersion); if (toolsetElement == null) { yield break; } foreach (ToolsetElement.PropertyElement propertyElement in toolsetElement.PropertyElements) { ElementLocation location = ElementLocation.Create(propertyElement.ElementInformation.Source, propertyElement.ElementInformation.LineNumber, 0); if (propertyElement.Name != null && propertyElement.Name.Length == 0) { InvalidToolsetDefinitionException.Throw("InvalidToolsetValueInConfigFileValue", location.LocationString); } yield return(new ToolsetPropertyDefinition(propertyElement.Name, propertyElement.Value, location)); } }
/// <summary> /// Provides an enumerator over the set of sub-toolset names available to a particular /// toolsversion /// </summary> /// <param name="toolsVersion">The tools version.</param> /// <returns>An enumeration of the sub-toolsets that belong to that toolsversion.</returns> protected override IEnumerable <string> GetSubToolsetVersions(string toolsVersion) { RegistryKeyWrapper toolsVersionWrapper = null; try { try { toolsVersionWrapper = _msbuildRegistryWrapper.OpenSubKey("ToolsVersions\\" + toolsVersion); } catch (RegistryException ex) { InvalidToolsetDefinitionException.Throw(ex, "RegistryReadError", ex.Source, ex.Message); } return(toolsVersionWrapper.GetSubKeyNames()); } finally { toolsVersionWrapper?.Dispose(); } }
/// <summary> /// Given a registry location containing a property name and value, create the ToolsetPropertyDefinition that maps to it /// </summary> /// <param name="toolsetWrapper">Wrapper for the key that we're getting values from</param> /// <param name="propertyName">The name of the property whose value we wish to generate a ToolsetPropertyDefinition for.</param> /// <returns>A ToolsetPropertyDefinition instance corresponding to the property name requested.</returns> private static ToolsetPropertyDefinition CreatePropertyFromRegistry(RegistryKeyWrapper toolsetWrapper, string propertyName) { string propertyValue = null; if (propertyName != null && propertyName.Length == 0) { InvalidToolsetDefinitionException.Throw("PropertyNameInRegistryHasZeroLength", toolsetWrapper.Name); } try { propertyValue = GetValue(toolsetWrapper, propertyName); } catch (RegistryException ex) { InvalidToolsetDefinitionException.Throw(ex, "RegistryReadError", ex.Source, ex.Message); } // For the purposes of error location, use the registry path instead of a file name IElementLocation location = new RegistryLocation(toolsetWrapper.Name + "@" + propertyName); return(new ToolsetPropertyDefinition(propertyName, propertyValue, location)); }
/// <summary> /// Reads the settings for a specified tools version /// </summary> private Toolset ReadToolset ( ToolsetPropertyDefinition toolsVersion, PropertyDictionary <ProjectPropertyInstance> globalProperties, PropertyDictionary <ProjectPropertyInstance> initialProperties, bool accumulateProperties ) { // Initial properties is the set of properties we're going to use to expand property expressions like $(foo) // in the values we read out of the registry or config file. We'll add to it as we pick up properties (including binpath) // from the registry or config file, so that properties there can be referenced in values below them. // After processing all the properties, we don't need initialProperties anymore. string toolsPath = null; string binPath = null; PropertyDictionary <ProjectPropertyInstance> properties = new PropertyDictionary <ProjectPropertyInstance>(); IEnumerable <ToolsetPropertyDefinition> rawProperties = GetPropertyDefinitions(toolsVersion.Name); Expander <ProjectPropertyInstance, ProjectItemInstance> expander = new Expander <ProjectPropertyInstance, ProjectItemInstance>(initialProperties, FileSystems.Default); foreach (ToolsetPropertyDefinition property in rawProperties) { EvaluateAndSetProperty(property, properties, globalProperties, initialProperties, accumulateProperties, ref toolsPath, ref binPath, ref expander); } Dictionary <string, SubToolset> subToolsets = new Dictionary <string, SubToolset>(StringComparer.OrdinalIgnoreCase); IEnumerable <string> subToolsetVersions = GetSubToolsetVersions(toolsVersion.Name); foreach (string subToolsetVersion in subToolsetVersions) { string subToolsetToolsPath = null; string subToolsetBinPath = null; IEnumerable <ToolsetPropertyDefinition> rawSubToolsetProperties = GetSubToolsetPropertyDefinitions(toolsVersion.Name, subToolsetVersion); PropertyDictionary <ProjectPropertyInstance> subToolsetProperties = new PropertyDictionary <ProjectPropertyInstance>(); // If we have a sub-toolset, any values defined here will override the toolset properties. foreach (ToolsetPropertyDefinition property in rawSubToolsetProperties) { EvaluateAndSetProperty(property, subToolsetProperties, globalProperties, initialProperties, false /* do not ever accumulate sub-toolset properties */, ref subToolsetToolsPath, ref subToolsetBinPath, ref expander); } if (subToolsetToolsPath != null || subToolsetBinPath != null) { InvalidToolsetDefinitionException.Throw("MSBuildToolsPathNotSupportedInSubToolsets", toolsVersion.Name, toolsVersion.Source.LocationString, subToolsetVersion); } subToolsets[subToolsetVersion] = new SubToolset(subToolsetVersion, subToolsetProperties); } // All tools versions must specify a value for MSBuildToolsPath (or MSBuildBinPath) if (String.IsNullOrEmpty(toolsPath) && String.IsNullOrEmpty(binPath)) { return(null); } // If both MSBuildBinPath and MSBuildToolsPath are present, they must be the same if (toolsPath != null && binPath != null && !toolsPath.Equals(binPath, StringComparison.OrdinalIgnoreCase)) { InvalidToolsetDefinitionException.Throw("ConflictingValuesOfMSBuildToolsPath", toolsVersion.Name, toolsVersion.Source.LocationString); } AppendStandardProperties(properties, globalProperties, toolsVersion.Name, null, toolsPath); Toolset toolset = null; try { var importSearchPathsTable = GetProjectImportSearchPathsTable(toolsVersion.Name, NativeMethodsShared.GetOSNameForExtensionsPath()); toolset = new Toolset(toolsVersion.Name, toolsPath == null ? binPath : toolsPath, properties, _environmentProperties, globalProperties, subToolsets, MSBuildOverrideTasksPath, DefaultOverrideToolsVersion, importSearchPathsTable); } catch (ArgumentException e) { InvalidToolsetDefinitionException.Throw("ErrorCreatingToolset", toolsVersion.Name, e.Message); } return(toolset); }