Пример #1
0
        public void ReadRegistry_DeletedKey()
        {
            DeleteTestRegistryKey();
            
            ToolsetReader reader = new ToolsetRegistryReader(new MockRegistryKey(testRegistryPath));
            ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None));

            string defaultToolsVersion = reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), false);
            Assertion.AssertEquals(0, values.Count);
        }
Пример #2
0
        public void DefaultValuesInRegistryCreatedBySetup()
        {
            ToolsetReader reader = new ToolsetRegistryReader();  //we don't use the test registry key because we want to verify the install

            ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None));

            string defaultToolsVersion = reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), false);

            // Check the values in the data
            Assertion.Assert("Tools version 4.0 should be defined by default", values.Contains("4.0"));
            Assertion.AssertEquals("Default tools version should be 2.0", "2.0", defaultToolsVersion);

            if (FrameworkLocationHelper.PathToDotNetFrameworkV35 != null)
            {
                Assertion.Assert("Tools version 2.0 should be defined by default if .NET FX 3.5 exists on the machine.", values.Contains("2.0"));
                Assertion.Assert("Tools version 3.5 should be defined by default if .NET FX 3.5 exists on the machine.", values.Contains("3.5"));
            }
        }
Пример #3
0
        public void GetDefaultToolsVersionFromRegistry_NonStringData()
        {
            currentVersionRegistryKey.SetValue("DefaultToolsVersion", new String[] { "2.0.xxxx.a", "2.0.xxxx.b" }, RegistryValueKind.MultiString);

            ToolsetReader reader = new ToolsetRegistryReader(new MockRegistryKey(testRegistryPath));
            ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None));
            string defaultToolsVersion = reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), false);
        }
Пример #4
0
        public void GetDefaultToolsVersionFromRegistry_Basic()
        {
            currentVersionRegistryKey.SetValue("DefaultToolsVersion", "tv1");
            RegistryKey key1 = toolsVersionsRegistryKey.CreateSubKey("tv1"); // Need matching tools version
            key1.SetValue("msbuildtoolspath", "c:\\xxx");

            ToolsetReader reader = new ToolsetRegistryReader(new MockRegistryKey(testRegistryPath));
            ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None));
            string defaultToolsVersion = reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), false);

            Assertion.AssertEquals("tv1", defaultToolsVersion);
        }
Пример #5
0
        public void GetDefaultToolsVersionFromRegistry_DefaultValueNotSet()
        {
            ToolsetReader reader = new ToolsetRegistryReader(new MockRegistryKey(testRegistryPath));
            ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None));
            string defaultToolsVersion = reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), false);

            Assertion.AssertEquals(null, defaultToolsVersion);
        }
Пример #6
0
        public void ReadRegistry_NonStringData()
        {
            RegistryKey key1 = toolsVersionsRegistryKey.CreateSubKey("tv1");
            key1.SetValue("msbuildtoolspath", "c:\\xxx");
            key1.SetValue("name1", "value1");
            RegistryKey key2 = toolsVersionsRegistryKey.CreateSubKey("tv2");
            key2.SetValue("msbuildtoolspath", "c:\\xxx");
            key2.SetValue("name2", new String[] { "value2a", "value2b" }, RegistryValueKind.MultiString);

            ToolsetReader reader = new ToolsetRegistryReader(new MockRegistryKey(testRegistryPath));
            ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None));
            string defaultToolsVersion = reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), false);
        }
Пример #7
0
        public void ReadRegistry_IgnoreSubKeysExceptTopMostSubKeys()
        {
            RegistryKey key1 = toolsVersionsRegistryKey.CreateSubKey("tv1");
            key1.SetValue("msbuildtoolspath", "c:\\xxx");
            key1.SetValue("name1", "value1");
            RegistryKey subKey1 = key1.CreateSubKey("SubKey1");
            subKey1.SetValue("name1a", "value1a");
            subKey1.SetValue("name2a", "value2a");
            RegistryKey key2 = toolsVersionsRegistryKey.CreateSubKey("tv2");
            key2.SetValue("msbuildtoolspath", "c:\\yyy");
            key2.SetValue("name2", "value2");
            RegistryKey subKey2 = key2.CreateSubKey("SubKey2");
            subKey2.SetValue("name3a", "value3a");
            subKey2.SetValue("name2a", "value2a");

            ToolsetReader reader = new ToolsetRegistryReader(new MockRegistryKey(testRegistryPath));
            ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None));
            string defaultToolsVersion = reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), false);

            Assertion.AssertEquals(2, values.Count);
            Assertion.AssertEquals(1, values["tv1"].BuildProperties.Count);
            Assertion.Assert(0 == String.Compare("c:\\xxx", values["tv1"].ToolsPath, StringComparison.OrdinalIgnoreCase));
            Assertion.Assert(0 == String.Compare("value1", values["tv1"].BuildProperties["name1"].Value, StringComparison.OrdinalIgnoreCase));
            Assertion.AssertEquals(1, values["tv2"].BuildProperties.Count);
            Assertion.Assert(0 == String.Compare("c:\\yyy", values["tv2"].ToolsPath, StringComparison.OrdinalIgnoreCase));
            Assertion.Assert(0 == String.Compare("value2", values["tv2"].BuildProperties["name2"].Value, StringComparison.OrdinalIgnoreCase));
        }
Пример #8
0
        public void ReadRegistry_OnlyOneSubkey()
        {
            RegistryKey key1 = toolsVersionsRegistryKey.CreateSubKey("tv1");
            key1.SetValue("msbuildtoolspath", "c:\\xxx");

            ToolsetReader reader = new ToolsetRegistryReader(new MockRegistryKey(testRegistryPath));
            ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None));
            string defaultToolsVersion = reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), false);

            Assertion.AssertEquals(null, defaultToolsVersion);
            Assertion.AssertEquals(1, values.Count);
            Assertion.AssertEquals(0, values["tv1"].BuildProperties.Count);
            Assertion.Assert(0 == String.Compare("c:\\xxx", values["tv1"].ToolsPath, StringComparison.OrdinalIgnoreCase));
        }
Пример #9
0
        public void ReadRegistry_NoSubkeysOnlyValues()
        {
            toolsVersionsRegistryKey.SetValue("Name1", "Value1");
            toolsVersionsRegistryKey.SetValue("Name2", "Value2");

            ToolsetReader reader = new ToolsetRegistryReader(new MockRegistryKey(testRegistryPath));
            ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None));
            string defaultToolsVersion = reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), false);

            Assertion.AssertEquals(0, values.Count);
            Assertion.AssertEquals(null, defaultToolsVersion);
        }
Пример #10
0
        public void DefaultValueInRegistryDoesNotExist()
        {
            ToolsetReader reader = new ToolsetRegistryReader(new MockRegistryKey(testRegistryPath, "3.5" /* fail to find subkey 3.5 */));

            ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None));

            // Should not throw
            string defaultToolsVersion = reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), false);

            Assertion.AssertEquals(null, defaultToolsVersion);
        }
        /// <summary>
        /// Gathers toolset data from the registry and configuration file, if any.
        /// NOTE:  this method is internal for unit testing purposes only.
        /// </summary>
        /// <param name="toolsets"></param>
        /// <param name="registryReader"></param>
        /// <param name="configurationReader"></param>
        /// <param name="globalProperties"></param>
        /// <param name="initialProperties"></param>
        /// <param name="locations"></param>
        /// <returns></returns>
        internal static string ReadAllToolsets(ToolsetCollection toolsets,
                                               ToolsetRegistryReader registryReader,
                                               ToolsetConfigurationReader configurationReader,
                                               BuildPropertyGroup globalProperties,
                                               BuildPropertyGroup initialProperties,
                                               ToolsetDefinitionLocations locations)
        {
            // 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, and we're reading the registry, create a toolset for it.
            // The registry and config file can overwrite it.
            if (
                ((locations & ToolsetDefinitionLocations.Registry) != 0) &&
                !toolsets.Contains("2.0") &&
                FrameworkLocationHelper.PathToDotNetFrameworkV20 != null
                )
            {
                Toolset synthetic20Toolset = new Toolset("2.0", FrameworkLocationHelper.PathToDotNetFrameworkV20, initialProperties);
                toolsets.Add(synthetic20Toolset);
            }

            // The ordering here is important because the configuration file should have greater precedence
            // than the registry
            string defaultToolsVersionFromRegistry = null;

            ToolsetRegistryReader registryReaderToUse = null;

            if ((locations & ToolsetDefinitionLocations.Registry) == ToolsetDefinitionLocations.Registry)
            {
                registryReaderToUse = registryReader ?? new ToolsetRegistryReader();
                // 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 =
                    registryReaderToUse.ReadToolsets(toolsets, globalProperties, initialProperties, false /* do not accumulate properties */);
            }

            string defaultToolsVersionFromConfiguration = null;

            ToolsetConfigurationReader configurationReaderToUse = null;

            if ((locations & ToolsetDefinitionLocations.ConfigurationFile) == ToolsetDefinitionLocations.ConfigurationFile)
            {
                if (configurationReader == null && 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();
                }

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

            // 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.Contains(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.Contains(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.Contains(defaultToolsVersion))
                    {
                        Toolset defaultToolset = new Toolset(defaultToolsVersion, pathToFramework, initialProperties);
                        toolsets.Add(defaultToolset);
                    }
                }
            }

            return(defaultToolsVersion);
        }
Пример #12
0
        /// <summary>
        /// Gathers toolset data from the registry and configuration file, if any.
        /// NOTE:  this method is internal for unit testing purposes only.
        /// </summary>
        /// <param name="toolsets"></param>
        /// <param name="registryReader"></param>
        /// <param name="configurationReader"></param>
        /// <param name="globalProperties"></param>
        /// <param name="initialProperties"></param>
        /// <param name="locations"></param>
        /// <returns></returns>
        internal static string ReadAllToolsets(ToolsetCollection toolsets,
                                               ToolsetRegistryReader registryReader,
                                               ToolsetConfigurationReader configurationReader,
                                               BuildPropertyGroup globalProperties,
                                               BuildPropertyGroup initialProperties,
                                               ToolsetDefinitionLocations locations)
        {
            // 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, and we're reading the registry, create a toolset for it. 
            // The registry and config file can overwrite it.
            if (
                ((locations & ToolsetDefinitionLocations.Registry) != 0) &&
                !toolsets.Contains("2.0") &&
                FrameworkLocationHelper.PathToDotNetFrameworkV20 != null
              )
            {
                Toolset synthetic20Toolset = new Toolset("2.0", FrameworkLocationHelper.PathToDotNetFrameworkV20, initialProperties);
                toolsets.Add(synthetic20Toolset);
            }

            // The ordering here is important because the configuration file should have greater precedence
            // than the registry
            string defaultToolsVersionFromRegistry = null;

            ToolsetRegistryReader registryReaderToUse = null;
            if ((locations & ToolsetDefinitionLocations.Registry) == ToolsetDefinitionLocations.Registry)
            {
                registryReaderToUse = registryReader == null ? new ToolsetRegistryReader() : registryReader;
                // 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 = 
                    registryReaderToUse.ReadToolsets(toolsets, globalProperties, initialProperties, false /* do not accumulate properties */);
            }

            string defaultToolsVersionFromConfiguration = null;
            
            ToolsetConfigurationReader configurationReaderToUse = null;
            if ((locations & ToolsetDefinitionLocations.ConfigurationFile) == ToolsetDefinitionLocations.ConfigurationFile)
            {
                if (configurationReader == null && 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();
                }

                if (configurationReader != null)
                {
                    configurationReaderToUse = configurationReader == null ? new ToolsetConfigurationReader() : configurationReader;
                    // Accumulation of properties is okay in the config file because it's deterministically ordered
                    defaultToolsVersionFromConfiguration =
                        configurationReaderToUse.ReadToolsets(toolsets, globalProperties, initialProperties, true /* accumulate properties */);
                }
            }
            
            // 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.Contains(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.Contains(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.Contains(defaultToolsVersion))
                    {
                        Toolset defaultToolset = new Toolset(defaultToolsVersion, pathToFramework, initialProperties);
                        toolsets.Add(defaultToolset);
                    }
                }
            }

            return defaultToolsVersion;
        }