/// <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);
            }
        }
Example #2
0
        /// <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))
            {
#if FEATURE_SPECIAL_FOLDERS
                localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
#else
                localAppData = FileUtilities.GetFolderPath(FileUtilities.SpecialFolder.LocalApplicationData);
#endif
            }

            if (String.IsNullOrEmpty(localAppData))
            {
#if FEATURE_SPECIAL_FOLDERS
                localAppData = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
#else
                localAppData = FileUtilities.GetFolderPath(FileUtilities.SpecialFolder.ApplicationData);
#endif
            }

            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));

            if (environmentVariablesBag != null)
            {
                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.IllegalItemPropertyNames[environmentVariableName] == null &&
                        !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);
        }