コード例 #1
0
ファイル: Project.cs プロジェクト: nikson/msbuild
        /// <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;
                        }
                    }
                }
            }
        }