Пример #1
0
        public bool Execute()
        {
            //set up support for logging
            TaskLoggingHelper loggingHelper = new TaskLoggingHelper(this);
            loggingHelper.LogMessageFromText(
            "Hello MSBuild", MessageImportance.High);

            return true;
        }
 internal static bool GetTableWithEscaping(TaskLoggingHelper log, string parameterName, string syntaxName, string[] propertyNameValueStrings, out Hashtable finalPropertiesTable)
 {
     finalPropertiesTable = null;
     if (propertyNameValueStrings != null)
     {
         finalPropertiesTable = new Hashtable(StringComparer.OrdinalIgnoreCase);
         List<PropertyNameValuePair> list = new List<PropertyNameValuePair>();
         foreach (string str in propertyNameValueStrings)
         {
             int index = str.IndexOf('=');
             if (index != -1)
             {
                 string propertyName = str.Substring(0, index).Trim();
                 string propertyValue = Microsoft.Build.Shared.EscapingUtilities.Escape(str.Substring(index + 1).Trim());
                 if (propertyName.Length == 0)
                 {
                     if (log != null)
                     {
                         log.LogErrorWithCodeFromResources("General.InvalidPropertyError", new object[] { syntaxName, str });
                     }
                     return false;
                 }
                 list.Add(new PropertyNameValuePair(propertyName, propertyValue));
             }
             else if (list.Count > 0)
             {
                 string str4 = Microsoft.Build.Shared.EscapingUtilities.Escape(str.Trim());
                 list[list.Count - 1].Value.Append(';');
                 list[list.Count - 1].Value.Append(str4);
             }
             else
             {
                 if (log != null)
                 {
                     log.LogErrorWithCodeFromResources("General.InvalidPropertyError", new object[] { syntaxName, str });
                 }
                 return false;
             }
         }
         if (log != null)
         {
             log.LogMessageFromText(parameterName, MessageImportance.Low);
         }
         foreach (PropertyNameValuePair pair in list)
         {
             finalPropertiesTable[pair.Name] = pair.Value.ToString();
             if (log != null)
             {
                 log.LogMessageFromText(string.Format(CultureInfo.InvariantCulture, "  {0}={1}", new object[] { pair.Name, pair.Value.ToString() }), MessageImportance.Low);
             }
         }
     }
     return true;
 }
Пример #3
0
        /// <summary>
        /// 
        /// </summary>
        /// <returns>True if the operation was successful</returns>
        internal static bool ExecuteTargets
            (
            ITaskItem[] projects,
            Hashtable propertiesTable,
            string[] undefineProperties,
            ArrayList targetLists,
            bool stopOnFirstFailure,
            bool rebaseOutputs,
            IBuildEngine3 buildEngine,
            TaskLoggingHelper log,
            ArrayList targetOutputs,
            bool useResultsCache,
            bool unloadProjectsOnCompletion,
            string toolsVersion
            )
        {
            bool success = true;

            // We don't log a message about the project and targets we're going to
            // build, because it'll all be in the immediately subsequent ProjectStarted event.

            string[] projectDirectory = new string[projects.Length];
            string[] projectNames = new string[projects.Length];
            string[] toolsVersions = new string[projects.Length];
            IList<IDictionary<string, ITaskItem[]>> targetOutputsPerProject = null;
            IDictionary[] projectProperties = new IDictionary[projects.Length];
            List<string>[] undefinePropertiesPerProject = new List<string>[projects.Length];

            for (int i = 0; i < projectNames.Length; i++)
            {
                projectNames[i] = null;
                projectProperties[i] = propertiesTable;

                if (projects[i] != null)
                {
                    // Retrieve projectDirectory only the first time.  It never changes anyway.
                    string projectPath = FileUtilities.AttemptToShortenPath(projects[i].ItemSpec);
                    projectDirectory[i] = Path.GetDirectoryName(projectPath);
                    projectNames[i] = projects[i].ItemSpec;
                    toolsVersions[i] = toolsVersion;


                    // If the user specified a different set of global properties for this project, then
                    // parse the string containing the properties
                    if (!String.IsNullOrEmpty(projects[i].GetMetadata("Properties")))
                    {
                        Hashtable preProjectPropertiesTable;
                        if (!PropertyParser.GetTableWithEscaping
                             (log, ResourceUtilities.FormatResourceString("General.OverridingProperties", projectNames[i]), "Properties", projects[i].GetMetadata("Properties").Split(';'),
                              out preProjectPropertiesTable)
                           )
                        {
                            return false;
                        }
                        projectProperties[i] = preProjectPropertiesTable;
                    }

                    if (undefineProperties != null)
                    {
                        undefinePropertiesPerProject[i] = new List<string>(undefineProperties);
                    }

                    // If the user wanted to undefine specific global properties for this project, parse
                    // that string and remove them now.
                    string projectUndefineProperties = projects[i].GetMetadata("UndefineProperties");
                    if (!String.IsNullOrEmpty(projectUndefineProperties))
                    {
                        string[] propertiesToUndefine = projectUndefineProperties.Split(new char[] { ';' });
                        if (undefinePropertiesPerProject[i] == null)
                        {
                            undefinePropertiesPerProject[i] = new List<string>(propertiesToUndefine.Length);
                        }

                        if (log != null && propertiesToUndefine.Length > 0)
                        {
                            log.LogMessageFromResources(MessageImportance.Low, "General.ProjectUndefineProperties", projectNames[i]);
                            foreach (string property in propertiesToUndefine)
                            {
                                undefinePropertiesPerProject[i].Add(property);
                                log.LogMessageFromText(String.Format(CultureInfo.InvariantCulture, "  {0}", property), MessageImportance.Low);
                            }
                        }
                    }

                    // If the user specified a different set of global properties for this project, then
                    // parse the string containing the properties
                    if (!String.IsNullOrEmpty(projects[i].GetMetadata("AdditionalProperties")))
                    {
                        Hashtable additionalProjectPropertiesTable;
                        if (!PropertyParser.GetTableWithEscaping
                             (log, ResourceUtilities.FormatResourceString("General.AdditionalProperties", projectNames[i]), "AdditionalProperties", projects[i].GetMetadata("AdditionalProperties").Split(';'),
                              out additionalProjectPropertiesTable)
                           )
                        {
                            return false;
                        }
                        Hashtable combinedTable = new Hashtable(StringComparer.OrdinalIgnoreCase);
                        // First copy in the properties from the global table that not in the additional properties table
                        if (projectProperties[i] != null)
                        {
                            foreach (DictionaryEntry entry in projectProperties[i])
                            {
                                if (!additionalProjectPropertiesTable.Contains(entry.Key))
                                {
                                    combinedTable.Add(entry.Key, entry.Value);
                                }
                            }
                        }
                        // Add all the additional properties
                        foreach (DictionaryEntry entry in additionalProjectPropertiesTable)
                        {
                            combinedTable.Add(entry.Key, entry.Value);
                        }
                        projectProperties[i] = combinedTable;
                    }

                    // If the user specified a different toolsVersion for this project - then override the setting
                    if (!String.IsNullOrEmpty(projects[i].GetMetadata("ToolsVersion")))
                    {
                        toolsVersions[i] = projects[i].GetMetadata("ToolsVersion");
                    }
                }
            }

            foreach (string[] targetList in targetLists)
            {
                if (stopOnFirstFailure && !success)
                {
                    // Inform the user that we skipped the remaining targets StopOnFirstFailure=true.
                    log.LogMessageFromResources(MessageImportance.Low, "MSBuild.SkippingRemainingTargets");

                    // We have encountered a failure.  Caller has requested that we not 
                    // continue with remaining targets.
                    break;
                }

                // Send the project off to the build engine.  By passing in null to the 
                // first param, we are indicating that the project to build is the same
                // as the *calling* project file.
                bool currentTargetResult = true;

                BuildEngineResult result =
                    buildEngine.BuildProjectFilesInParallel(projectNames, targetList, projectProperties, undefinePropertiesPerProject, toolsVersions, true /* ask that target outputs are returned in the buildengineresult */);

                currentTargetResult = result.Result;
                targetOutputsPerProject = result.TargetOutputsPerProject;
                success = success && currentTargetResult;

                // If the engine was able to satisfy the build request
                if (currentTargetResult)
                {
                    for (int i = 0; i < projects.Length; i++)
                    {
                        IEnumerable nonNullTargetList = (targetList != null) ? targetList : targetOutputsPerProject[i].Keys;

                        foreach (string targetName in nonNullTargetList)
                        {
                            if (targetOutputsPerProject[i].ContainsKey(targetName))
                            {
                                ITaskItem[] outputItemsFromTarget = (ITaskItem[])targetOutputsPerProject[i][targetName];

                                foreach (ITaskItem outputItemFromTarget in outputItemsFromTarget)
                                {
                                    // No need to rebase if the calling project is the same as the callee project 
                                    // (project == null).  Also no point in trying to copy item metadata either,
                                    // because no items were passed into the Projects parameter!
                                    if (projects[i] != null)
                                    {
                                        // Rebase the output item paths if necessary.  No need to rebase if the calling
                                        // project is the same as the callee project (project == null).
                                        if (rebaseOutputs)
                                        {
                                            try
                                            {
                                                outputItemFromTarget.ItemSpec = Path.Combine(projectDirectory[i], outputItemFromTarget.ItemSpec);
                                            }
                                            catch (ArgumentException e)
                                            {
                                                log.LogWarningWithCodeFromResources(null, projects[i].ItemSpec, 0, 0, 0, 0, "MSBuild.CannotRebaseOutputItemPath", outputItemFromTarget.ItemSpec, e.Message);
                                            }
                                        }

                                        // Copy the custom item metadata from the "Projects" items to these
                                        // output items.
                                        projects[i].CopyMetadataTo(outputItemFromTarget);

                                        // Set a metadata on the output items called "MSBuildProjectFile" which tells you which project file produced this item.
                                        if (String.IsNullOrEmpty(outputItemFromTarget.GetMetadata(ItemMetadataNames.msbuildSourceProjectFile)))
                                        {
                                            outputItemFromTarget.SetMetadata(ItemMetadataNames.msbuildSourceProjectFile, projects[i].GetMetadata(FileUtilities.ItemSpecModifiers.FullPath));
                                        }
                                    }

                                    // Set a metadata on the output items called "MSBuildTargetName" which tells you which target produced this item.
                                    if (String.IsNullOrEmpty(outputItemFromTarget.GetMetadata(ItemMetadataNames.msbuildSourceTargetName)))
                                    {
                                        outputItemFromTarget.SetMetadata(ItemMetadataNames.msbuildSourceTargetName, targetName);
                                    }
                                }

                                targetOutputs.AddRange(outputItemsFromTarget);
                            }
                        }
                    }
                }
            }

            return success;
        }