/// <summary>
        /// Gathers toolset data from the registry and configuration file, if any.
        /// NOTE:  this method is internal for unit testing purposes only.
        /// </summary>
        internal static string ReadAllToolsets
        (
            Dictionary <string, Toolset> toolsets,
#if FEATURE_WIN32_REGISTRY
            ToolsetRegistryReader registryReader,
#endif
#if FEATURE_SYSTEM_CONFIGURATION
            ToolsetConfigurationReader configurationReader,
#endif
            PropertyDictionary <ProjectPropertyInstance> environmentProperties,
            PropertyDictionary <ProjectPropertyInstance> globalProperties,
            ToolsetDefinitionLocations locations
        )
        {
            var initialProperties =
                new PropertyDictionary <ProjectPropertyInstance>(environmentProperties);

            initialProperties.ImportProperties(globalProperties);

            // The ordering here is important because the configuration file should have greater precedence
            // than the registry, and we do a check and don't read in the new toolset if there's already one.
            string defaultToolsVersionFromConfiguration         = null;
            string overrideTasksPathFromConfiguration           = null;
            string defaultOverrideToolsVersionFromConfiguration = null;

#if FEATURE_SYSTEM_CONFIGURATION
            if ((locations & ToolsetDefinitionLocations.ConfigurationFile) == ToolsetDefinitionLocations.ConfigurationFile)
            {
                if (configurationReader == null)
                {
                    configurationReader = new ToolsetConfigurationReader(environmentProperties, globalProperties);
                }

                // Accumulation of properties is okay in the config file because it's deterministically ordered
                defaultToolsVersionFromConfiguration = configurationReader.ReadToolsets(toolsets, globalProperties,
                                                                                        initialProperties, true /* accumulate properties */, out overrideTasksPathFromConfiguration,
                                                                                        out defaultOverrideToolsVersionFromConfiguration);
            }
#endif

            string defaultToolsVersionFromRegistry         = null;
            string overrideTasksPathFromRegistry           = null;
            string defaultOverrideToolsVersionFromRegistry = null;

            if ((locations & ToolsetDefinitionLocations.Registry) == ToolsetDefinitionLocations.Registry)
            {
#if FEATURE_WIN32_REGISTRY
                if (NativeMethodsShared.IsWindows || registryReader != null)
                {
                    // If we haven't been provided a registry reader (i.e. unit tests), create one
                    registryReader = registryReader ?? new ToolsetRegistryReader(environmentProperties, globalProperties);

                    // We do not accumulate properties when reading them from the registry, because the order
                    // in which values are returned to us is essentially random: so we disallow one property
                    // in the registry to refer to another also in the registry
                    defaultToolsVersionFromRegistry = registryReader.ReadToolsets(toolsets, globalProperties,
                                                                                  initialProperties, false /* do not accumulate properties */, out overrideTasksPathFromRegistry,
                                                                                  out defaultOverrideToolsVersionFromRegistry);
                }
                else
#endif
                {
                    var currentDir = BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory.TrimEnd(Path.DirectorySeparatorChar);
                    var props      = new PropertyDictionary <ProjectPropertyInstance>();

                    var libraryPath = NativeMethodsShared.FrameworkBasePath;

                    if (!string.IsNullOrEmpty(libraryPath))
                    {
                        // The 4.0 toolset is installed in the framework directory
                        var v4Dir =
                            FrameworkLocationHelper.GetPathToDotNetFrameworkV40(DotNetFrameworkArchitecture.Current);
                        if (v4Dir != null && !toolsets.ContainsKey("4.0"))
                        {
                            // Create standard properties. On Mono they are well known
                            var buildProperties =
                                CreateStandardProperties(globalProperties, "4.0", libraryPath, v4Dir);

                            toolsets.Add(
                                "4.0",
                                new Toolset(
                                    "4.0",
                                    v4Dir,
                                    buildProperties,
                                    environmentProperties,
                                    globalProperties,
                                    null,
                                    currentDir,
                                    string.Empty));
                        }

                        // Other toolsets are installed in the xbuild directory
                        var xbuildToolsetsDir = Path.Combine(libraryPath, $"xbuild{Path.DirectorySeparatorChar}");
                        if (FileSystems.Default.DirectoryExists(xbuildToolsetsDir))
                        {
                            var r = new Regex(Regex.Escape(xbuildToolsetsDir) + @"\d+\.\d+");
                            foreach (var d in Directory.GetDirectories(xbuildToolsetsDir).Where(d => r.IsMatch(d)))
                            {
                                var version = Path.GetFileName(d);
                                var binPath = Path.Combine(d, "bin");
                                if (toolsets.ContainsKey(version))
                                {
                                    continue;
                                }

                                if (NativeMethodsShared.IsMono && Version.TryParse(version, out Version parsedVersion) && parsedVersion.Major > 14)
                                {
                                    continue;
                                }

                                // Create standard properties. On Mono they are well known
                                var buildProperties =
                                    CreateStandardProperties(globalProperties, version, xbuildToolsetsDir, binPath);

                                toolsets.Add(
                                    version,
                                    new Toolset(
                                        version,
                                        binPath,
                                        buildProperties,
                                        environmentProperties,
                                        globalProperties,
                                        null,
                                        currentDir,
                                        string.Empty));
                            }
                        }
                    }
                    if (!toolsets.ContainsKey(MSBuildConstants.CurrentToolsVersion))
                    {
                        toolsets.Add(
                            MSBuildConstants.CurrentToolsVersion,
                            new Toolset(
                                MSBuildConstants.CurrentToolsVersion,
                                currentDir,
                                props,
                                new PropertyDictionary <ProjectPropertyInstance>(),
                                currentDir,
                                string.Empty));
                    }
                }
            }

            // The 2.0 .NET Framework installer did not write a ToolsVersion key for itself in the registry.
            // The 3.5 installer writes one for 2.0, but 3.5 might not be installed.
            // The 4.0 and subsequent installers can't keep writing the 2.0 one, because (a) it causes SxS issues and (b) we
            // don't want it unless 2.0 is installed.
            // So if the 2.0 framework is actually installed, we're reading the registry, and either the registry or the config
            // file have not already created the 2.0 toolset, mock up a fake one.
            if (((locations & ToolsetDefinitionLocations.Registry) != 0) && !toolsets.ContainsKey("2.0") &&
                FrameworkLocationHelper.PathToDotNetFrameworkV20 != null)
            {
                var synthetic20Toolset = new Toolset(
                    "2.0",
                    FrameworkLocationHelper.PathToDotNetFrameworkV20,
                    environmentProperties,
                    globalProperties,
                    null /* 2.0 did not have override tasks */,
                    null /* 2.0 did not have a default override toolsversion */);
                toolsets.Add("2.0", synthetic20Toolset);
            }

            string defaultToolsVersionFromLocal         = null;
            string overrideTasksPathFromLocal           = null;
            string defaultOverrideToolsVersionFromLocal = null;

            if ((locations & ToolsetDefinitionLocations.Local) == ToolsetDefinitionLocations.Local)
            {
                var localReader = new ToolsetLocalReader(environmentProperties, globalProperties);

                defaultToolsVersionFromLocal = localReader.ReadToolsets(
                    toolsets,
                    globalProperties,
                    initialProperties,
                    false /* accumulate properties */,
                    out overrideTasksPathFromLocal,
                    out defaultOverrideToolsVersionFromLocal);
            }

            // We'll use the path from the configuration file if it was specified, otherwise we'll try
            // the one from the registry.  It's possible (and valid) that neither the configuration file
            // nor the registry specify a override in which case we'll just return null.
            var overrideTasksPath = overrideTasksPathFromConfiguration ?? overrideTasksPathFromRegistry ?? overrideTasksPathFromLocal;

            // We'll use the path from the configuration file if it was specified, otherwise we'll try
            // the one from the registry.  It's possible (and valid) that neither the configuration file
            // nor the registry specify a override in which case we'll just return null.
            var defaultOverrideToolsVersion = defaultOverrideToolsVersionFromConfiguration
                                              ?? defaultOverrideToolsVersionFromRegistry
                                              ?? defaultOverrideToolsVersionFromLocal;

            // We'll use the default from the configuration file if it was specified, otherwise we'll try
            // the one from the registry.  It's possible (and valid) that neither the configuration file
            // nor the registry specify a default, in which case we'll just return null.
            var defaultToolsVersion = defaultToolsVersionFromConfiguration ?? defaultToolsVersionFromRegistry ?? defaultToolsVersionFromLocal;

            // If we got a default version from the registry or config file, and it
            // actually exists, fine.
            // Otherwise we have to come up with one.
            if (defaultToolsVersion != null && toolsets.ContainsKey(defaultToolsVersion))
            {
                return(defaultToolsVersion);
            }
            // We're going to choose a hard coded default tools version of 2.0.
            defaultToolsVersion = Constants.defaultToolsVersion;

            // But don't overwrite any existing tools path for this default we're choosing.
            if (toolsets.ContainsKey(Constants.defaultToolsVersion))
            {
                return(defaultToolsVersion);
            }
            // There's no tools path already for 2.0, so use the path to the v2.0 .NET Framework.
            // If an old-fashioned caller sets BinPath property, or passed a BinPath to the constructor,
            // that will overwrite what we're setting here.
            ErrorUtilities.VerifyThrow(
                Constants.defaultToolsVersion == "2.0",
                "Getting 2.0 FX path so default should be 2.0");
            var pathToFramework = FrameworkLocationHelper.PathToDotNetFrameworkV20;

            // We could not find the default toolsversion because it was not installed on the machine. Fallback to the
            // one we expect to always be there when running msbuild 4.0.
            if (pathToFramework == null)
            {
                pathToFramework     = FrameworkLocationHelper.PathToDotNetFrameworkV40;
                defaultToolsVersion = Constants.defaultFallbackToolsVersion;
            }

            // Again don't overwrite any existing tools path for this default we're choosing.
            if (toolsets.ContainsKey(defaultToolsVersion))
            {
                return(defaultToolsVersion);
            }
            var defaultToolset = new Toolset(
                defaultToolsVersion,
                pathToFramework,
                environmentProperties,
                globalProperties,
                overrideTasksPath,
                defaultOverrideToolsVersion);
            toolsets.Add(defaultToolsVersion, defaultToolset);

            return(defaultToolsVersion);
        }
Esempio n. 2
0
        /// <summary>
        /// Gathers toolset data from the registry and configuration file, if any.
        /// NOTE:  this method is internal for unit testing purposes only.
        /// </summary>
        internal static string ReadAllToolsets
            (
            Dictionary<string, Toolset> toolsets,
            ToolsetRegistryReader registryReader,
            ToolsetConfigurationReader configurationReader,
            PropertyDictionary<ProjectPropertyInstance> environmentProperties,
            PropertyDictionary<ProjectPropertyInstance> globalProperties,
            ToolsetDefinitionLocations locations
            )
        {
            PropertyDictionary<ProjectPropertyInstance> initialProperties = new PropertyDictionary<ProjectPropertyInstance>(environmentProperties);

            initialProperties.ImportProperties(globalProperties);

            // The ordering here is important because the configuration file should have greater precedence
            // than the registry, and we do a check and don't read in the new toolset if there's already one. 
            string defaultToolsVersionFromConfiguration = null;
            string overrideTasksPathFromConfiguration = null;
            string defaultOverrideToolsVersionFromConfiguration = null;

            if ((locations & ToolsetDefinitionLocations.ConfigurationFile) == ToolsetDefinitionLocations.ConfigurationFile)
            {
                if (configurationReader == null && ToolsetConfigurationReaderHelpers.ConfigurationFileMayHaveToolsets())
                {
                    // We haven't been passed in a fake configuration reader by a unit test,
                    // and it looks like we have a .config file to read, so create a real
                    // configuration reader
                    configurationReader = new ToolsetConfigurationReader(environmentProperties, globalProperties);
                }

                if (configurationReader != null)
                {
                    // Accumulation of properties is okay in the config file because it's deterministically ordered
                    defaultToolsVersionFromConfiguration = configurationReader.ReadToolsets(toolsets, globalProperties,
                        initialProperties, true /* accumulate properties */, out overrideTasksPathFromConfiguration,
                        out defaultOverrideToolsVersionFromConfiguration);
                }
            }

            string defaultToolsVersionFromRegistry = null;
            string overrideTasksPathFromRegistry = null;
            string defaultOverrideToolsVersionFromRegistry = null;

            if ((locations & ToolsetDefinitionLocations.Registry) == ToolsetDefinitionLocations.Registry)
            {
                // If we haven't been provided a registry reader (i.e. unit tests), create one
                registryReader = registryReader ?? new ToolsetRegistryReader(environmentProperties, globalProperties);

                // We do not accumulate properties when reading them from the registry, because the order
                // in which values are returned to us is essentially random: so we disallow one property
                // in the registry to refer to another also in the registry
                defaultToolsVersionFromRegistry = registryReader.ReadToolsets(toolsets, globalProperties,
                    initialProperties, false /* do not accumulate properties */, out overrideTasksPathFromRegistry,
                    out defaultOverrideToolsVersionFromRegistry);
            }

            // The 2.0 .NET Framework installer did not write a ToolsVersion key for itself in the registry. 
            // The 3.5 installer writes one for 2.0, but 3.5 might not be installed.  
            // The 4.0 and subsequent installers can't keep writing the 2.0 one, because (a) it causes SxS issues and (b) we 
            // don't want it unless 2.0 is installed.
            // So if the 2.0 framework is actually installed, we're reading the registry, and either the registry or the config
            // file have not already created the 2.0 toolset, mock up a fake one.  
            if (
                ((locations & ToolsetDefinitionLocations.Registry) != 0) &&
                !toolsets.ContainsKey("2.0") &&
                FrameworkLocationHelper.PathToDotNetFrameworkV20 != null
              )
            {
                Toolset synthetic20Toolset = new Toolset("2.0", FrameworkLocationHelper.PathToDotNetFrameworkV20, environmentProperties, globalProperties, null /* 2.0 did not have override tasks */, null /* 2.0 did not have a default override toolsversion */);
                toolsets.Add("2.0", synthetic20Toolset);
            }

            // We'll use the path from the configuration file if it was specified, otherwise we'll try
            // the one from the registry.  It's possible (and valid) that neither the configuration file
            // nor the registry specify a override in which case we'll just return null.
            string overrideTasksPath = overrideTasksPathFromConfiguration ?? overrideTasksPathFromRegistry;

            // We'll use the path from the configuration file if it was specified, otherwise we'll try
            // the one from the registry.  It's possible (and valid) that neither the configuration file
            // nor the registry specify a override in which case we'll just return null.
            string defaultOverrideToolsVersion = defaultOverrideToolsVersionFromConfiguration ?? defaultOverrideToolsVersionFromRegistry;

            // We'll use the default from the configuration file if it was specified, otherwise we'll try
            // the one from the registry.  It's possible (and valid) that neither the configuration file
            // nor the registry specify a default, in which case we'll just return null.
            string defaultToolsVersion = defaultToolsVersionFromConfiguration ?? defaultToolsVersionFromRegistry;

            // If we got a default version from the registry or config file, and it
            // actually exists, fine.
            // Otherwise we have to come up with one.
            if (defaultToolsVersion == null || !toolsets.ContainsKey(defaultToolsVersion))
            {
                // We're going to choose a hard coded default tools version of 2.0.
                defaultToolsVersion = Constants.defaultToolsVersion;

                // But don't overwrite any existing tools path for this default we're choosing.
                if (!toolsets.ContainsKey(Constants.defaultToolsVersion))
                {
                    // There's no tools path already for 2.0, so use the path to the v2.0 .NET Framework.
                    // If an old-fashioned caller sets BinPath property, or passed a BinPath to the constructor,
                    // that will overwrite what we're setting here.
                    ErrorUtilities.VerifyThrow(Constants.defaultToolsVersion == "2.0", "Getting 2.0 FX path so default should be 2.0");
                    string pathToFramework = FrameworkLocationHelper.PathToDotNetFrameworkV20;

                    // We could not find the default toolsversion because it was not installed on the machine. Fallback to the 
                    // one we expect to always be there when running msbuild 4.0.
                    if (pathToFramework == null)
                    {
                        pathToFramework = FrameworkLocationHelper.PathToDotNetFrameworkV40;
                        defaultToolsVersion = Constants.defaultFallbackToolsVersion;
                    }

                    // Again don't overwrite any existing tools path for this default we're choosing.
                    if (!toolsets.ContainsKey(defaultToolsVersion))
                    {
                        Toolset defaultToolset = new Toolset(defaultToolsVersion, pathToFramework, environmentProperties, globalProperties, overrideTasksPath, defaultOverrideToolsVersion);
                        toolsets.Add(defaultToolsVersion, defaultToolset);
                    }
                }
            }

            return defaultToolsVersion;
        }
        public void DefaultValueInRegistryDoesNotExist()
        {
            ToolsetReader reader = new ToolsetRegistryReader(new ProjectCollection().EnvironmentProperties, new PropertyDictionary<ProjectPropertyInstance>(), new MockRegistryKey(testRegistryPath, "3.5" /* fail to find subkey 3.5 */));

            Dictionary<string, Toolset> values = new Dictionary<string, Toolset>(StringComparer.OrdinalIgnoreCase);

            // Should not throw
            string msbuildOverrideTasksPath = null;
            string defaultOverrideToolsVersion = null;
            string defaultToolsVersion = reader.ReadToolsets(values, new PropertyDictionary<ProjectPropertyInstance>(), new PropertyDictionary<ProjectPropertyInstance>(), false, out msbuildOverrideTasksPath, out defaultOverrideToolsVersion);

            Assert.Equal(null, defaultToolsVersion);
        }
Esempio n. 4
0
        /// <summary>
        /// Gathers toolset data from the registry and configuration file, if any.
        /// NOTE:  this method is internal for unit testing purposes only.
        /// </summary>
        internal static string ReadAllToolsets
        (
            Dictionary <string, Toolset> toolsets,
            ToolsetRegistryReader registryReader,
            ToolsetConfigurationReader configurationReader,
            PropertyDictionary <ProjectPropertyInstance> environmentProperties,
            PropertyDictionary <ProjectPropertyInstance> globalProperties,
            ToolsetDefinitionLocations locations
        )
        {
            PropertyDictionary <ProjectPropertyInstance> initialProperties = new PropertyDictionary <ProjectPropertyInstance>(environmentProperties);

            initialProperties.ImportProperties(globalProperties);

            // The ordering here is important because the configuration file should have greater precedence
            // than the registry, and we do a check and don't read in the new toolset if there's already one.
            string defaultToolsVersionFromConfiguration         = null;
            string overrideTasksPathFromConfiguration           = null;
            string defaultOverrideToolsVersionFromConfiguration = null;

            if ((locations & ToolsetDefinitionLocations.ConfigurationFile) == ToolsetDefinitionLocations.ConfigurationFile)
            {
                if (configurationReader == null && ToolsetConfigurationReaderHelpers.ConfigurationFileMayHaveToolsets())
                {
                    // We haven't been passed in a fake configuration reader by a unit test,
                    // and it looks like we have a .config file to read, so create a real
                    // configuration reader
                    configurationReader = new ToolsetConfigurationReader(environmentProperties, globalProperties);
                }

                if (configurationReader != null)
                {
                    // Accumulation of properties is okay in the config file because it's deterministically ordered
                    defaultToolsVersionFromConfiguration = configurationReader.ReadToolsets(toolsets, globalProperties,
                                                                                            initialProperties, true /* accumulate properties */, out overrideTasksPathFromConfiguration,
                                                                                            out defaultOverrideToolsVersionFromConfiguration);
                }
            }

            string defaultToolsVersionFromRegistry         = null;
            string overrideTasksPathFromRegistry           = null;
            string defaultOverrideToolsVersionFromRegistry = null;

            if ((locations & ToolsetDefinitionLocations.Registry) == ToolsetDefinitionLocations.Registry)
            {
                // If we haven't been provided a registry reader (i.e. unit tests), create one
                registryReader = registryReader ?? new ToolsetRegistryReader(environmentProperties, globalProperties);

                // We do not accumulate properties when reading them from the registry, because the order
                // in which values are returned to us is essentially random: so we disallow one property
                // in the registry to refer to another also in the registry
                defaultToolsVersionFromRegistry = registryReader.ReadToolsets(toolsets, globalProperties,
                                                                              initialProperties, false /* do not accumulate properties */, out overrideTasksPathFromRegistry,
                                                                              out defaultOverrideToolsVersionFromRegistry);
            }

            // The 2.0 .NET Framework installer did not write a ToolsVersion key for itself in the registry.
            // The 3.5 installer writes one for 2.0, but 3.5 might not be installed.
            // The 4.0 and subsequent installers can't keep writing the 2.0 one, because (a) it causes SxS issues and (b) we
            // don't want it unless 2.0 is installed.
            // So if the 2.0 framework is actually installed, we're reading the registry, and either the registry or the config
            // file have not already created the 2.0 toolset, mock up a fake one.
            if (
                ((locations & ToolsetDefinitionLocations.Registry) != 0) &&
                !toolsets.ContainsKey("2.0") &&
                FrameworkLocationHelper.PathToDotNetFrameworkV20 != null
                )
            {
                Toolset synthetic20Toolset = new Toolset("2.0", FrameworkLocationHelper.PathToDotNetFrameworkV20, environmentProperties, globalProperties, null /* 2.0 did not have override tasks */, null /* 2.0 did not have a default override toolsversion */);
                toolsets.Add("2.0", synthetic20Toolset);
            }

            // We'll use the path from the configuration file if it was specified, otherwise we'll try
            // the one from the registry.  It's possible (and valid) that neither the configuration file
            // nor the registry specify a override in which case we'll just return null.
            string overrideTasksPath = overrideTasksPathFromConfiguration ?? overrideTasksPathFromRegistry;

            // We'll use the path from the configuration file if it was specified, otherwise we'll try
            // the one from the registry.  It's possible (and valid) that neither the configuration file
            // nor the registry specify a override in which case we'll just return null.
            string defaultOverrideToolsVersion = defaultOverrideToolsVersionFromConfiguration ?? defaultOverrideToolsVersionFromRegistry;

            // We'll use the default from the configuration file if it was specified, otherwise we'll try
            // the one from the registry.  It's possible (and valid) that neither the configuration file
            // nor the registry specify a default, in which case we'll just return null.
            string defaultToolsVersion = defaultToolsVersionFromConfiguration ?? defaultToolsVersionFromRegistry;

            // If we got a default version from the registry or config file, and it
            // actually exists, fine.
            // Otherwise we have to come up with one.
            if (defaultToolsVersion == null || !toolsets.ContainsKey(defaultToolsVersion))
            {
                // We're going to choose a hard coded default tools version of 2.0.
                defaultToolsVersion = Constants.defaultToolsVersion;

                // But don't overwrite any existing tools path for this default we're choosing.
                if (!toolsets.ContainsKey(Constants.defaultToolsVersion))
                {
                    // There's no tools path already for 2.0, so use the path to the v2.0 .NET Framework.
                    // If an old-fashioned caller sets BinPath property, or passed a BinPath to the constructor,
                    // that will overwrite what we're setting here.
                    ErrorUtilities.VerifyThrow(Constants.defaultToolsVersion == "2.0", "Getting 2.0 FX path so default should be 2.0");
                    string pathToFramework = FrameworkLocationHelper.PathToDotNetFrameworkV20;

                    // We could not find the default toolsversion because it was not installed on the machine. Fallback to the
                    // one we expect to always be there when running msbuild 4.0.
                    if (pathToFramework == null)
                    {
                        pathToFramework     = FrameworkLocationHelper.PathToDotNetFrameworkV40;
                        defaultToolsVersion = Constants.defaultFallbackToolsVersion;
                    }

                    // Again don't overwrite any existing tools path for this default we're choosing.
                    if (!toolsets.ContainsKey(defaultToolsVersion))
                    {
                        Toolset defaultToolset = new Toolset(defaultToolsVersion, pathToFramework, environmentProperties, globalProperties, overrideTasksPath, defaultOverrideToolsVersion);
                        toolsets.Add(defaultToolsVersion, defaultToolset);
                    }
                }
            }

            return(defaultToolsVersion);
        }
        // Ignore: Test requires installed toolset.
        public void DefaultValuesInRegistryCreatedBySetup()
        {
            ToolsetReader reader = new ToolsetRegistryReader(new ProjectCollection().EnvironmentProperties, new PropertyDictionary<ProjectPropertyInstance>());  //we don't use the test registry key because we want to verify the install

            Dictionary<string, Toolset> values = new Dictionary<string, Toolset>(StringComparer.OrdinalIgnoreCase);

            string msbuildOverrideTasksPath = null;
            string defaultOverrideToolsVersion = null;
            string defaultToolsVersion = reader.ReadToolsets(values, new PropertyDictionary<ProjectPropertyInstance>(), new PropertyDictionary<ProjectPropertyInstance>(), false, out msbuildOverrideTasksPath, out defaultOverrideToolsVersion);

            // Check the values in the data
            Assert.True(values.ContainsKey("4.0")); // "Tools version 4.0 should be defined by default"
            Assert.True(values.ContainsKey(ObjectModelHelpers.MSBuildDefaultToolsVersion), String.Format("Tools version {0} should be defined by default", ObjectModelHelpers.MSBuildDefaultToolsVersion));
            Assert.Equal("2.0", defaultToolsVersion); // "Default tools version should be 2.0"
        }