/// <summary> /// Processes a particular ToolsetPropertyDefinition into the correct value and location in the initial and/or final property set. /// </summary> /// <param name="property">The ToolsetPropertyDefinition being analyzed.</param> /// <param name="properties">The final set of properties that we wish this toolset property to be added to. </param> /// <param name="globalProperties">The global properties, used for expansion and to make sure none are overridden.</param> /// <param name="initialProperties">The initial properties, used for expansion and added to if "accumulateProperties" is true.</param> /// <param name="accumulateProperties">If "true", we add this property to the initialProperties dictionary, as well, so that properties later in the toolset can use this value.</param> /// <param name="toolsPath">If this toolset property is the "MSBuildToolsPath" property, we will return the value in this parameter.</param> /// <param name="binPath">If this toolset property is the "MSBuildBinPath" property, we will return the value in this parameter.</param> /// <param name="expander">The expander used to expand the value of the properties. Ref because if we are accumulating the properties, we need to re-create the expander to account for the new property value.</param> private void EvaluateAndSetProperty(ToolsetPropertyDefinition property, PropertyDictionary <ProjectPropertyInstance> properties, PropertyDictionary <ProjectPropertyInstance> globalProperties, PropertyDictionary <ProjectPropertyInstance> initialProperties, bool accumulateProperties, ref string toolsPath, ref string binPath, ref Expander <ProjectPropertyInstance, ProjectItemInstance> expander) { if (0 == String.Compare(property.Name, ReservedPropertyNames.toolsPath, StringComparison.OrdinalIgnoreCase)) { toolsPath = ExpandPropertyUnescaped(property, expander); toolsPath = ExpandRelativePathsRelativeToExeLocation(toolsPath); if (accumulateProperties) { SetProperty ( new ToolsetPropertyDefinition(ReservedPropertyNames.toolsPath, toolsPath, property.Source), initialProperties, globalProperties ); } } else if (0 == String.Compare(property.Name, ReservedPropertyNames.binPath, StringComparison.OrdinalIgnoreCase)) { binPath = ExpandPropertyUnescaped(property, expander); binPath = ExpandRelativePathsRelativeToExeLocation(binPath); if (accumulateProperties) { SetProperty ( new ToolsetPropertyDefinition(ReservedPropertyNames.binPath, binPath, property.Source), initialProperties, globalProperties ); } } else if (ReservedPropertyNames.IsReservedProperty(property.Name)) { // We don't allow toolsets to define reserved properties string baseMessage = ResourceUtilities.FormatResourceStringStripCodeAndKeyword("CannotModifyReservedProperty", property.Name); InvalidToolsetDefinitionException.Throw("InvalidPropertyNameInToolset", property.Name, property.Source.LocationString, baseMessage); } else { // It's an arbitrary property property.Value = ExpandPropertyUnescaped(property, expander); SetProperty(property, properties, globalProperties); if (accumulateProperties) { SetProperty(property, initialProperties, globalProperties); } } if (accumulateProperties) { expander = new Expander <ProjectPropertyInstance, ProjectItemInstance>(initialProperties, FileSystems.Default); } }
/// <summary> /// Retrieves properties derived from the current /// environment variables. /// </summary> internal static PropertyDictionary <ProjectPropertyInstance> GetEnvironmentProperties() { IDictionary <string, string> environmentVariablesBag = CommunicationsUtilities.GetEnvironmentVariables(); PropertyDictionary <ProjectPropertyInstance> environmentProperties = new PropertyDictionary <ProjectPropertyInstance>(environmentVariablesBag.Count + 2); // We set the MSBuildExtensionsPath variables here because we don't want to make them official // reserved properties; we need the ability for people to override our default in their // environment or as a global property. #if !FEATURE_INSTALLED_MSBUILD string extensionsPath = BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory; string extensionsPath32 = extensionsPath; #else // "MSBuildExtensionsPath32". This points to whatever the value of "Program Files (x86)" environment variable is; // but on a 32 bit box this isn't set, and we should use "Program Files" instead. string programFiles32 = FrameworkLocationHelper.programFiles32; string extensionsPath32 = NativeMethodsShared.IsWindows ? Path.Combine(programFiles32, ReservedPropertyNames.extensionsPathSuffix) : programFiles32; #endif environmentProperties.Set(ProjectPropertyInstance.Create(ReservedPropertyNames.extensionsPath32, extensionsPath32, true)); #if !FEATURE_INSTALLED_MSBUILD string extensionsPath64 = extensionsPath; environmentProperties.Set(ProjectPropertyInstance.Create(ReservedPropertyNames.extensionsPath64, extensionsPath64, true)); #else // "MSBuildExtensionsPath64". This points to whatever the value of "Program Files" environment variable is on a // 64-bit machine, and is empty on a 32-bit machine. if (FrameworkLocationHelper.programFiles64 != null) { // if ProgramFiles and ProgramFiles(x86) are the same, then this is a 32-bit box, // so we only want to set MSBuildExtensionsPath64 if they're not string extensionsPath64 = NativeMethodsShared.IsWindows ? Path.Combine( FrameworkLocationHelper.programFiles64, ReservedPropertyNames.extensionsPathSuffix) : FrameworkLocationHelper.programFiles64; environmentProperties.Set(ProjectPropertyInstance.Create(ReservedPropertyNames.extensionsPath64, extensionsPath64, true)); } #endif #if FEATURE_INSTALLED_MSBUILD // MSBuildExtensionsPath: The way this used to work is that it would point to "Program Files\MSBuild" on both // 32-bit and 64-bit machines. We have a switch to continue using that behavior; however the default is now for // MSBuildExtensionsPath to always point to the same location as MSBuildExtensionsPath32. bool useLegacyMSBuildExtensionsPathBehavior = !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("MSBUILDLEGACYEXTENSIONSPATH")); string programFiles = FrameworkLocationHelper.programFiles; string extensionsPath; if (useLegacyMSBuildExtensionsPathBehavior) { extensionsPath = Path.Combine(programFiles, ReservedPropertyNames.extensionsPathSuffix); } else { extensionsPath = extensionsPath32; } #endif environmentProperties.Set(ProjectPropertyInstance.Create(ReservedPropertyNames.extensionsPath, extensionsPath, true)); // Windows XP and Windows Server 2003 don't define LocalAppData in their environment. // We'll set it here if the environment doesn't have it so projects can reliably // depend on $(LocalAppData). string localAppData = String.Empty; ProjectPropertyInstance localAppDataProp = environmentProperties.GetProperty(ReservedPropertyNames.localAppData); if (localAppDataProp != null) { localAppData = localAppDataProp.EvaluatedValue; } if (String.IsNullOrEmpty(localAppData)) { localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); } if (String.IsNullOrEmpty(localAppData)) { localAppData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData); } if (String.IsNullOrEmpty(localAppData)) { localAppData = BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory; } environmentProperties.Set(ProjectPropertyInstance.Create(ReservedPropertyNames.localAppData, localAppData)); // Add MSBuildUserExtensionsPath at $(LocalAppData)\Microsoft\MSBuild string userExtensionsPath = Path.Combine(localAppData, ReservedPropertyNames.userExtensionsPathSuffix); environmentProperties.Set(ProjectPropertyInstance.Create(ReservedPropertyNames.userExtensionsPath, userExtensionsPath)); foreach (KeyValuePair <string, string> environmentVariable in environmentVariablesBag) { // We're going to just skip environment variables that contain names // with characters we can't handle. There's no logger registered yet // when this method is called, so we can't really log anything. string environmentVariableName = environmentVariable.Key; if (XmlUtilities.IsValidElementName(environmentVariableName) && !XMakeElements.ReservedItemNames.Contains(environmentVariableName) && !ReservedPropertyNames.IsReservedProperty(environmentVariableName)) { ProjectPropertyInstance environmentProperty = ProjectPropertyInstance.Create(environmentVariableName, environmentVariable.Value); environmentProperties.Set(environmentProperty); } else { // The name was invalid, so we just didn't add the environment variable. // That's fine, continue for the next one. } } return(environmentProperties); }