Example #1
0
		internal void Add (Import import)
		{
			if (!filenames.ContainsKey (import.EvaluatedProjectPath)) {
				groupingCollection.Add (import);
				filenames.Add (import.EvaluatedProjectPath, import);
			}
		}
Example #2
0
        /// <summary>
        /// Changes the value of the ProjectPath property on an existing import.
        /// Note: this methods causes the project to recreate all imports, so existing import
        /// instances might not be affected.
        /// </summary>
        public static void SetImportProjectPath(MSBuildBasedProject project, MSBuild.Import import,
                                                string newRawPath)
        {
            if (project == null)
            {
                throw new ArgumentNullException("project");
            }
            if (import == null)
            {
                throw new ArgumentNullException("import");
            }
            if (newRawPath == null)
            {
                throw new ArgumentNullException("newRawPath");
            }

            lock (project.SyncRoot) {
                XmlAttribute a = (XmlAttribute)typeof(MSBuild.Import).InvokeMember(
                    "ProjectPathAttribute",
                    BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic,
                    null, import, null
                    );
                a.Value = newRawPath;
                EndXmlManipulation(project.MSBuildProject);
            }
            project.CreateItemsListFromMSBuild();
        }
Example #3
0
        public void TestICollectionMethods()
        {
            ObjectModelHelpers.DeleteTempProjectDirectory();

            ObjectModelHelpers.CreateFileInTempProjectDirectory("import1.proj", @"
                    <Project xmlns=`msbuildnamespace`>
                    </Project>
                ");

            ObjectModelHelpers.CreateFileInTempProjectDirectory("import2.proj", @"
                    <Project xmlns=`msbuildnamespace`>
                    </Project>
                ");

            ObjectModelHelpers.CreateFileInTempProjectDirectory("main.proj", @"

                    <Project xmlns=`msbuildnamespace`>

                        <Import Project=`import1.proj` />
                        <Import Project=`import2.proj` />

                        <Target Name=`Build`>
                            <WashCar/>
                        </Target>

                    </Project>

                ");

            Project project = ObjectModelHelpers.LoadProjectFileInTempProjectDirectory("main.proj", null);

            string import1Path = Path.Combine(ObjectModelHelpers.TempProjectDir, "import1.proj");
            string import2Path = Path.Combine(ObjectModelHelpers.TempProjectDir, "import2.proj");

            ImportCollection imports = project.Imports;

            Assertion.AssertEquals(2, imports.Count);

            Import[] array = new Import[2];
            imports.CopyTo(array, 0);
            Dictionary<string, Import> hash = new Dictionary<string, Import>(StringComparer.OrdinalIgnoreCase);
            hash[array[0].EvaluatedProjectPath] = array[0];
            hash[array[1].EvaluatedProjectPath] = array[1];

            Assertion.AssertEquals(imports[import1Path], hash[import1Path]);
            Assertion.AssertEquals(imports[import2Path], hash[import2Path]);

            object[] arrayObjects = new object[2];
            imports.CopyTo(arrayObjects, 0);
            hash.Clear();
            hash[((Import)arrayObjects[0]).EvaluatedProjectPath] = ((Import)arrayObjects[0]);
            hash[((Import)arrayObjects[1]).EvaluatedProjectPath] = ((Import)arrayObjects[1]);

            Assertion.AssertEquals(imports[import1Path], hash[import1Path]);
            Assertion.AssertEquals(imports[import2Path], hash[import2Path]);

            Assertion.AssertEquals("import1.proj", imports[import1Path].ProjectPath);
            Assertion.AssertEquals("import2.proj", imports[import2Path].ProjectPath);
        }
		public void Imports()
		{
			// this is machine-dependent, it's possible that additional imports are loaded
			//Assert.AreEqual(2, project.MSBuildProject.Imports.Count);
			Microsoft.Build.BuildEngine.Import[] imports = new Microsoft.Build.BuildEngine.Import[project.MSBuildProject.Imports.Count];
			project.MSBuildProject.Imports.CopyTo(imports, 0);
			
			string[] paths = new string[imports.Length];
			for (int i = 0; i < imports.Length; i++) {
				paths[i] = imports[i].ProjectPath;
			}
			
			Assert.Contains(WixProject.DefaultTargetsFile, paths);
		}
        public void Imports()
        {
            // this is machine-dependent, it's possible that additional imports are loaded
            //Assert.AreEqual(2, project.MSBuildProject.Imports.Count);
            Microsoft.Build.BuildEngine.Import[] imports = new Microsoft.Build.BuildEngine.Import[project.MSBuildProject.Imports.Count];
            project.MSBuildProject.Imports.CopyTo(imports, 0);

            string[] paths = new string[imports.Length];
            for (int i = 0; i < imports.Length; i++)
            {
                paths[i] = imports[i].ProjectPath;
            }

            Assert.Contains(WixProject.DefaultTargetsFile, paths);
        }
Example #6
0
        /// <summary>
        /// Gets the import paths from the project.
        /// </summary>
        string[] GetImportPaths()
        {
            int count = project.MSBuildProject.Imports.Count;

            Microsoft.Build.BuildEngine.Import[] imports = new Microsoft.Build.BuildEngine.Import[count];
            project.MSBuildProject.Imports.CopyTo(imports, 0);

            string[] paths = new string[count];
            for (int i = 0; i < count; ++i)
            {
                Microsoft.Build.BuildEngine.Import import = imports[i];
                paths[i] = import.ProjectPath;
            }
            return(paths);
        }
		public void TestAdd1 ()
		{
			string first = @"
                                <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
					<Import Project='second.proj'/>
                                </Project>
";
			using (StreamWriter sw = new StreamWriter ("Test/resources/first.proj")) {
				sw.Write (first);
			}

			string second = @"
                                <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
                                </Project>
";
			using (StreamWriter sw = new StreamWriter ("Test/resources/second.proj")) {
				sw.Write (second);
			}

                        string documentString = @"
                                <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
						<Import Project='Test\resources\first.proj'/>
						<Import Project='Test\resources\Import.csproj' Condition='false'/>
                                </Project>
                        ";

                        engine = new Engine (Consts.BinPath);

                        project = engine.CreateNewProject ();
                        project.LoadXml (documentString);

			Import[] t = new Import [2];
			Assert.AreEqual (2, project.Imports.Count, "Number of imports");
			project.Imports.CopyTo (t, 0);

			string base_dir = Path.Combine (Environment.CurrentDirectory, Path.Combine ("Test", "resources"));

			Assert.IsNull (t [0].Condition, "A1");

			Assert.AreEqual (false, t[0].IsImported, "A5");
			Assert.AreEqual ("Test\\resources\\first.proj", t[0].ProjectPath, "A6");
			Assert.AreEqual (Path.Combine (base_dir, "first.proj"), t[0].EvaluatedProjectPath, "A7");

			Assert.AreEqual (true, t[1].IsImported, "A2");
			Assert.AreEqual ("second.proj", t[1].ProjectPath, "A3");
			Assert.AreEqual (Path.Combine (base_dir, "second.proj"), t[1].EvaluatedProjectPath, "A4");
		}
		internal void Add (Import import)
		{
			imports++;
			if (add_iterator == null)
				list.AddLast (import);
			else {
				list.AddAfter (add_iterator, import);
				add_iterator = add_iterator.Next;
			}
		}
Example #9
0
		public void CopyTo (Import[] array, int index)
		{
			CopyTo ((Array) array, index);
		}
Example #10
0
		internal bool TryGetImport (Import keyImport, out Import valueImport)
		{
			return filenames.TryGetValue (keyImport.EvaluatedProjectPath, out valueImport);
		}
Example #11
0
		internal bool Contains (Import import)
		{
			return filenames.ContainsKey (import.EvaluatedProjectPath);
		}
Example #12
0
        /// <summary>
        /// Removes an import from the project, and removes the corresponding &lt;Import&gt; element
        /// from the project's XML.
        /// </summary>
        /// <param name="importToRemove"></param>
        /// <owner>JeffCal</owner>
        public void RemoveImport
        (
            Import importToRemove
        )
        {
            ErrorUtilities.VerifyThrowArgumentNull(importToRemove, "importToRemove");

            // Confirm that it's not an imported import.
            ErrorUtilities.VerifyThrowInvalidOperation(!importToRemove.IsImported,
                "CannotModifyImportedProjects");

            // Confirm that the import belongs to this project.
            ErrorUtilities.VerifyThrowInvalidOperation(importToRemove.ParentProject == this.parentProject,
                "IncorrectObjectAssociation", "Import", "Project");

            // Remove the Xml for the <Import> from the <Project>.
            this.parentProject.ProjectElement.RemoveChild(importToRemove.ImportElement);

            // Remove the import from our hashtable.
            this.imports.Remove(importToRemove.EvaluatedProjectPath);
            
            // Dissociate the import from the parent project.
            importToRemove.ParentProject = null;

            // The project file has been modified and needs to be saved and re-evaluated.
            this.parentProject.MarkProjectAsDirtyForReprocessXml();
        }
Example #13
0
 /// <summary>
 /// Copy the contents of this collection into a strongly typed array
 /// </summary>
 /// <param name="array"></param>
 /// <param name="index"></param>
 /// <owner>LukaszG</owner>
 public void CopyTo(Import[] array, int index)
 {
     ErrorUtilities.VerifyThrow(this.imports != null, "ImportCollection's Hashtable not initialized!");
     this.imports.Values.CopyTo(array, index);
 }
Example #14
0
 public void SyncRoot()
 {
     string importPath = String.Empty;
     string importPath2 = String.Empty;
     try
     {
         importPath = ObjectModelHelpers.CreateFileInTempProjectDirectory("import.proj", TestData.Content3SimpleTargetsDefaultSpecified);
         importPath2 = ObjectModelHelpers.CreateFileInTempProjectDirectory("import2.proj", TestData.Content3SimpleTargetsDefaultSpecified);
         Project p = new Project();
         p.Imports.AddNewImport(importPath, "true");
         p.Imports.AddNewImport(importPath2, "true");
         object o = p.EvaluatedItems;
         Import[] importArray = new Import[p.Imports.Count];
         p.Imports.CopyTo(importArray, 0);
         lock (p.Imports.SyncRoot) 
         {
             int i = 0;
             foreach (Import import in p.Imports) 
             {
                 Assertion.AssertEquals(importArray[i].ProjectPath, import.ProjectPath);
                i++;
             }
         }
     }
     finally
     {
         CompatibilityTestHelpers.RemoveFile(importPath);
         CompatibilityTestHelpers.RemoveFile(importPath2);
     }
 }
Example #15
0
 public void CopyToStrong_OffsetIndex()
 {
     string importPath = String.Empty;
     try
     {
         const int OffsetIndex = 2;
         importPath = ObjectModelHelpers.CreateFileInTempProjectDirectory("import.proj", TestData.Content3SimpleTargetsDefaultSpecified);
         Project p = new Project();
         p.Imports.AddNewImport(importPath, "true");
         object o = p.EvaluatedItems;
         Import import = CompatibilityTestHelpers.FindFirstMatchingImportByPath(p.Imports, importPath);
         Import[] importArray = new Import[p.Imports.Count + OffsetIndex];
         p.Imports.CopyTo(importArray, OffsetIndex);
         Assertion.AssertEquals(p.Imports.Count, importArray.Length - OffsetIndex);
         Assertion.AssertNull(importArray[OffsetIndex - 1]);
         Assertion.AssertEquals(true, 0 < Array.IndexOf(importArray, import));
     }
     finally
     {
         CompatibilityTestHelpers.RemoveFile(importPath);
     }
 }
Example #16
0
 internal bool Contains(Import import)
 {
     return(filenames.ContainsKey(import.EvaluatedProjectPath));
 }
Example #17
0
 internal bool TryGetImport(Import keyImport, out Import valueImport)
 {
     return(filenames.TryGetValue(keyImport.EvaluatedProjectPath, out valueImport));
 }
Example #18
0
 public void GetEnumerator()
 {
     string importPath = String.Empty;
     string importPath2 = String.Empty;
     try
     {
         importPath = ObjectModelHelpers.CreateFileInTempProjectDirectory("import.proj", TestData.Content3SimpleTargetsDefaultSpecified);
         importPath2 = ObjectModelHelpers.CreateFileInTempProjectDirectory("import2.proj", TestData.Content3SimpleTargetsDefaultSpecified);
         Project p = new Project();
         p.Imports.AddNewImport(importPath, "true");
         p.Imports.AddNewImport(importPath2, "true");
         object o = p.EvaluatedItems;
         Import[] importArray = new Import[p.Imports.Count];
         p.Imports.CopyTo(importArray, 0);
         System.Collections.IEnumerator importEnum = p.Imports.GetEnumerator();
         int enumerationCounter = 0;
         while (importEnum.MoveNext())
         {
             Assertion.AssertEquals(true, object.ReferenceEquals(importArray[enumerationCounter], importEnum.Current));
             Assertion.AssertEquals(importArray[enumerationCounter].ProjectPath, ((Import)importEnum.Current).ProjectPath);
             enumerationCounter++;
         }
     }
     finally
     {
         CompatibilityTestHelpers.RemoveFile(importPath);
         CompatibilityTestHelpers.RemoveFile(importPath2);
     }
 }
Example #19
0
        /// <summary>
        /// Process the &lt;Import&gt; element by loading the child project file, and processing its &lt;Project&gt; element. In a
        /// given main project, the same file cannot be imported twice -- this is to prevent circular imports.
        /// </summary>
        /// <owner>RGoel</owner>
        /// <param name="importElement"></param>
        /// <param name="projectDirectoryLocation"></param>
        /// <param name="importedProject"></param>
        private void ProcessImportElement
        (
            XmlElement  importElement,
            string      projectDirectoryLocation,
            bool        importedProject
        )
        {
            Import temp = new Import(importElement, this, importedProject);

            if (temp.ConditionAttribute != null)
            {
                // Do not expand properties or items before passing in the value of the
                // condition attribute to EvaluateCondition, otherwise special characters
                // inside the property values can really confuse the condition parser.
                if (!Utilities.EvaluateCondition(temp.Condition, temp.ConditionAttribute, 
                    new Expander(this.evaluatedProperties), this.conditionedPropertiesTable, 
                    ParserOptions.AllowProperties, ParentEngine.LoggingServices, projectBuildEventContext))
                {
                    return;
                }
            }

            // If we got this far, we expect the "Project" attribute to have a reasonable
            // value, so process it now.

            // Expand any $(propertyname) references inside the "Project" attribute value.
            string expandedImportedFilename = (new Expander(this.evaluatedProperties)).ExpandAllIntoStringLeaveEscaped(temp.ProjectPath, temp.ProjectPathAttribute);
            
            // Expand any wildcards
            string[] importedFilenames = EngineFileUtilities.GetFileListEscaped(projectDirectoryLocation, expandedImportedFilename);

            for (int i = 0; i < importedFilenames.Length; i++)
            {
                string importedFilename = EscapingUtilities.UnescapeAll(importedFilenames[i]);
                         
                ProjectErrorUtilities.VerifyThrowInvalidProject((importedFilename != null) && (importedFilename.Length != 0),
                    importElement, "MissingRequiredAttribute",
                    XMakeAttributes.project, XMakeElements.import);

                Import import = new Import(importElement, this, importedProject);

                try
                {
                    if (!string.IsNullOrEmpty(projectDirectoryLocation))
                    {
                        import.SetEvaluatedProjectPath(Path.GetFullPath(Path.Combine(projectDirectoryLocation, importedFilename)));
                    }
                    else
                    {
                        import.SetEvaluatedProjectPath(Path.GetFullPath(importedFilename));
                    }
                }
                catch (Exception e) // Catching Exception, but rethrowing unless it's an IO related exception.
                {
                    if (ExceptionHandling.NotExpectedException(e))
                        throw;

                    ProjectErrorUtilities.VerifyThrowInvalidProject(false, importElement, "InvalidAttributeValueWithException", importedFilename, XMakeAttributes.project, XMakeElements.import, e.Message);
                }

                XmlDocument importedDocument = LoadImportedProject(import);

                if (importedDocument != null)
                {
                    this.rawGroups.InsertAtEnd(import);

                    // Get the top-level nodes from the XML.
                    XmlNodeList importedFileNodes = importedDocument.ChildNodes;

                    // The XML parser will guarantee that we only have one real root element,
                    // but we need to find it amongst the other types of XmlNode at the root.
                    foreach (XmlNode importedChildNode in importedFileNodes)
                    {
                        if (XmlUtilities.IsXmlRootElement(importedChildNode))
                        {
                            // Save the current directory, so we can restore it back later.
                            string currentDirectory = Directory.GetCurrentDirectory();

                            // If we have a <VisualStudioProject> node, tell the user they must upgrade the project
                            ProjectErrorUtilities.VerifyThrowInvalidProject(importedChildNode.LocalName != XMakeElements.visualStudioProject,
                                importedChildNode, "ProjectUpgradeNeeded");

                            // This node must be a <Project> node.
                            ProjectErrorUtilities.VerifyThrowInvalidProject(importedChildNode.LocalName == XMakeElements.project,
                                importedChildNode, "UnrecognizedElement", importedChildNode.Name);

                            ProjectErrorUtilities.VerifyThrowInvalidProject((importedChildNode.Prefix.Length == 0) && (String.Compare(importedChildNode.NamespaceURI, XMakeAttributes.defaultXmlNamespace, StringComparison.OrdinalIgnoreCase) == 0),
                                importedChildNode, "ProjectMustBeInMSBuildXmlNamespace", XMakeAttributes.defaultXmlNamespace);


                            // We have the <Project> element, so process it.
                            this.ProcessProjectAttributes((XmlElement)importedChildNode,
                                /* imported project */ true);
                            this.ProcessProjectChildren((XmlElement)importedChildNode,
                                Path.GetDirectoryName(import.EvaluatedProjectPath),
                                /* imported project */ true);

                            break;
                        }
                    }
                }
            }
        }
Example #20
0
 public void CopyToStrong_IndexZero()
 {
     string importPath = String.Empty;
     try
     {
         importPath = ObjectModelHelpers.CreateFileInTempProjectDirectory("import.proj", TestData.Content3SimpleTargetsDefaultSpecified);
         Project p = new Project();
         p.Imports.AddNewImport(importPath, "true");
         object o = p.EvaluatedItems;
         Import import = CompatibilityTestHelpers.FindFirstMatchingImportByPath(p.Imports, importPath);
         Import[] importArray = new Import[p.Imports.Count];
         p.Imports.CopyTo(importArray, 0);
         Assertion.AssertEquals(p.Imports.Count, importArray.Length);
         Assertion.AssertEquals(0, Array.IndexOf(importArray, import));
         Assertion.AssertEquals(true, object.ReferenceEquals(importArray[Array.IndexOf(importArray, import)], import));
     }
     finally
     {
         CompatibilityTestHelpers.RemoveFile(importPath);
     }
 }
Example #21
0
        /// <summary>
        /// Loads the XML for the specified project that is being imported into the main project.
        /// </summary>
        /// <owner>RGoel, SumedhK</owner>
        /// <param name="import">The project being imported</param>
        /// <returns>XML for imported project; null, if duplicate import.</returns>
        private XmlDocument LoadImportedProject(Import import)
        {
            XmlDocument importedDocument = null;
            bool importedFileExists = File.Exists(import.EvaluatedProjectPath);

            // NOTE: don't use ErrorUtilities.VerifyThrowFileExists() here because that exception doesn't carry XML node
            // information, and we need that data to show a better error message

            if (!importedFileExists)
            {
                ProjectErrorUtilities.VerifyThrowInvalidProject((this.loadSettings & ProjectLoadSettings.IgnoreMissingImports) != 0,
                    import.ProjectPathAttribute, "ImportedProjectNotFound", import.EvaluatedProjectPath);
            }

            // Make sure that the file we're about to import hasn't been imported previously.
            // This is how we prevent circular dependencies.  It so happens that this mechanism
            // also prevents the same file from being imported twice, even it it's not a
            // circular dependency, but that's fine -- no good reason to do that anyway.
            if ((this.imports[import.EvaluatedProjectPath] != null) ||
                (string.Compare(this.FullFileName, import.EvaluatedProjectPath, StringComparison.OrdinalIgnoreCase) == 0))
            {
                ParentEngine.LoggingServices.LogWarning(projectBuildEventContext, Utilities.CreateBuildEventFileInfo(import.ProjectPathAttribute, FullFileName),
                    "DuplicateImport", import.EvaluatedProjectPath);
            }
            else
            {
                // See if the imported project is also a top-level project that has been loaded
                // by the engine.  If so, use the in-memory copy of the imported project instead
                // of reading the copy off of the disk.  This way, we can reflect any changes
                // that have been made to the in-memory copy.
                Project importedProject = this.ParentEngine.GetLoadedProject(import.EvaluatedProjectPath);
                if (importedProject != null)
                {
                    importedDocument = importedProject.XmlDocument;
                }
                // The imported project is not part of the engine, so read it off of disk.
                else
                {
                    // If the file doesn't exist on disk but we're told to ignore missing imports, simply skip it
                    if (importedFileExists)
                    {
                        // look up the engine's cache to see if we've already loaded this imported project on behalf of another
                        // top-level project
                        ImportedProject previouslyImportedProject = (ImportedProject)ParentEngine.ImportedProjectsCache[import.EvaluatedProjectPath];
                        
                        // if this project hasn't been imported before, or if it has changed on disk, we need to load it
                        if ((previouslyImportedProject == null) || previouslyImportedProject.HasChangedOnDisk(import.EvaluatedProjectPath))
                        {
                            try
                            {
                                // Do not validate the imported file against a schema.
                                // We only validate the parent project against a schema in V1, because without custom
                                // namespace support, we would have to pollute the msbuild namespace with everything that
                                // appears anywhere in our targets file.

                                // cache this imported project, so that if another top-level project also imports this project, we
                                // will not re-parse the XML (unless it changes)
                                previouslyImportedProject = new ImportedProject(import.EvaluatedProjectPath);
                                ParentEngine.ImportedProjectsCache[import.EvaluatedProjectPath] = previouslyImportedProject;
                            }
                            // catch XML exceptions early so that we still have the imported project file name
                            catch (XmlException e)
                            {
                                BuildEventFileInfo fileInfo = new BuildEventFileInfo(e);
                                ProjectFileErrorUtilities.VerifyThrowInvalidProjectFile(false,
                                    fileInfo,
                                    "InvalidImportedProjectFile", e.Message);
                            }
                            // catch IO exceptions, for example for when the file is in use. DDB #36839
                            catch (Exception e)
                            {
                                if (ExceptionHandling.NotExpectedException(e))
                                    throw;

                                BuildEventFileInfo fileInfo = new BuildEventFileInfo(import.EvaluatedProjectPath);
                                ProjectFileErrorUtilities.VerifyThrowInvalidProjectFile(false,
                                    fileInfo,
                                    "InvalidImportedProjectFile", e.Message);
                            }
                        }

                        importedDocument = previouslyImportedProject.Xml;
                    }
                }

                // Add the imported filename to our list, so we can be sure not to import
                // it again.  This helps prevent infinite recursion.
                this.imports[import.EvaluatedProjectPath] = import;
            }

            return importedDocument;
        }