/// <summary> /// Process the <Import> element by loading the child project file, and processing its <Project> 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; } } } } }