public override bool Execute()

in src/Tasks/MSBuild.cs [378:538]


        public override bool Execute()
        {
            // If no projects were passed in, just return success.
            if ((Projects == null) || (Projects.Length == 0))
            {
                return true;
            }

            // We have been asked to unescape all escaped characters before processing
            if (this.TargetAndPropertyListSeparators != null && this.TargetAndPropertyListSeparators.Length > 0)
            {
                ExpandAllTargetsAndProperties();
            }

            // Parse the global properties into a hashtable.
            Hashtable propertiesTable;
            if (!PropertyParser.GetTableWithEscaping(Log, ResourceUtilities.FormatResourceString("General.GlobalProperties"), "Properties", this.Properties, out propertiesTable))
            {
                return false;
            }

            // Parse out the properties to undefine, if any.
            string[] undefinePropertiesArray = null;
            if (!String.IsNullOrEmpty(_undefineProperties))
            {
                Log.LogMessageFromResources(MessageImportance.Low, "General.UndefineProperties");
                undefinePropertiesArray = _undefineProperties.Split(new char[] { ';' });
                foreach (string property in undefinePropertiesArray)
                {
                    Log.LogMessageFromText(String.Format(CultureInfo.InvariantCulture, "  {0}", property), MessageImportance.Low);
                }
            }

            bool isRunningMultipleNodes = BuildEngine2.IsRunningMultipleNodes;
            // If we are in single proc mode and stopOnFirstFailure is true, we cannot build in parallel because 
            // building in parallel sends all of the projects to the engine at once preventing us from not sending
            // any more projects after the first failure. Therefore, to preserve compatibility with whidbey if we are in this situation disable buildInParallel.
            if (!isRunningMultipleNodes && _stopOnFirstFailure && _buildInParallel)
            {
                _buildInParallel = false;
                Log.LogMessageFromResources(MessageImportance.Low, "MSBuild.NotBuildingInParallel");
            }

            // When the condition below is met, provide an information message indicating stopOnFirstFailure
            // will have no effect. The reason there will be no effect is, when buildInParallel is true
            // All project files will be submitted to the engine all at once, this mean there is no stopping for failures between projects.
            // When RunEachTargetSeparately is false, all targets will be submitted to the engine at once, this means there is no way to stop between target failures.
            // therefore the first failure seen will be the only failure seen.
            if (isRunningMultipleNodes && _buildInParallel && _stopOnFirstFailure && !_runEachTargetSeparately)
            {
                Log.LogMessageFromResources(MessageImportance.Low, "MSBuild.NoStopOnFirstFailure");
            }

            // This is a list of string[].  That is, each element in the list is a string[].  Each
            // string[] represents a set of target names to build.  Depending on the value 
            // of the RunEachTargetSeparately parameter, we each just call the engine to run all 
            // the targets together, or we call the engine separately for each target.
            ArrayList targetLists = CreateTargetLists(this.Targets, this.RunEachTargetSeparately);


            bool success = true;
            ITaskItem[] singleProject = null;
            bool[] skipProjects = null;


            if (_buildInParallel)
            {
                skipProjects = new bool[Projects.Length];
                for (int i = 0; i < skipProjects.Length; i++)
                {
                    skipProjects[i] = true;
                }
            }
            else
            {
                singleProject = new ITaskItem[1];
            }

            // Read in each project file.  If there are any errors opening the file or parsing the XML,
            // raise an event and return False.  If any one of the projects fails to build, return False,
            // otherwise return True. If parallel build is requested we first check for file existence so
            // that we don't pass a non-existent file to IBuildEngine causing an exception
            for (int i = 0; i < Projects.Length; i++)
            {
                ITaskItem project = Projects[i];

                string projectPath = FileUtilities.AttemptToShortenPath(project.ItemSpec);

                if (_stopOnFirstFailure && !success)
                {
                    // Inform the user that we skipped the remaining projects because StopOnFirstFailure=true.
                    Log.LogMessageFromResources(MessageImportance.Low, "MSBuild.SkippingRemainingProjects");

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

                if (File.Exists(projectPath) || (_skipNonexistentProjects == SkipNonexistentProjectsBehavior.Build))
                {
                    if (FileUtilities.IsVCProjFilename(projectPath))
                    {
                        Log.LogErrorWithCodeFromResources("MSBuild.ProjectUpgradeNeededToVcxProj", project.ItemSpec);
                        success = false;
                        continue;
                    }

                    // If we are building in parallel we want to only make one call to
                    // ExecuteTargets once we verified that all projects exist
                    if (!_buildInParallel)
                    {
                        singleProject[0] = project;

                        if (!ExecuteTargets
                                (
                                singleProject,
                                propertiesTable,
                                undefinePropertiesArray,
                                targetLists,
                                StopOnFirstFailure,
                                RebaseOutputs,
                                BuildEngine3,
                                Log,
                                _targetOutputs,
                                _useResultsCache,
                                _unloadProjectsOnCompletion,
                                ToolsVersion
                                )
                           )
                        {
                            success = false;
                        }
                    }
                    else
                    {
                        skipProjects[i] = false;
                    }
                }
                else
                {
                    if (_skipNonexistentProjects == SkipNonexistentProjectsBehavior.Skip)
                    {
                        Log.LogMessageFromResources(MessageImportance.High, "MSBuild.ProjectFileNotFoundMessage", project.ItemSpec);
                    }
                    else
                    {
                        ErrorUtilities.VerifyThrow(_skipNonexistentProjects == SkipNonexistentProjectsBehavior.Error, "skipNonexistentProjects has unexpected value {0}", _skipNonexistentProjects);
                        Log.LogErrorWithCodeFromResources("MSBuild.ProjectFileNotFound", project.ItemSpec);
                        success = false;
                    }
                }
            }

            // We need to build all the projects that were not skipped
            if (_buildInParallel)
            {
                success = BuildProjectsInParallel(propertiesTable, undefinePropertiesArray, targetLists, success, skipProjects);
            }

            return success;
        }