public static ExitType Execute()

in src/MSBuild/XMake.cs [473:767]


        public static ExitType Execute(
#if FEATURE_GET_COMMANDLINE
            string commandLine
#else
            string [] commandLine
#endif
            )
        {
            // Indicate to the engine that it can toss extraneous file content
            // when it loads microsoft.*.targets. We can't do this in the general case,
            // because tasks in the build can (and occasionally do) load MSBuild format files
            // with our OM and modify and save them. They'll never do this for Microsoft.*.targets, though,
            // and those form the great majority of our unnecessary memory use.
            Environment.SetEnvironmentVariable("MSBuildLoadMicrosoftTargetsReadOnly", "true");
            switch (Environment.GetEnvironmentVariable("MSBUILDDEBUGONSTART"))
            {
#if FEATURE_DEBUG_LAUNCH
                case "1":
                    Debugger.Launch();
                    break;
#endif
                case "2":
                    // Sometimes easier to attach rather than deal with JIT prompt
                    Process currentProcess = Process.GetCurrentProcess();
                    Console.WriteLine($"Waiting for debugger to attach ({currentProcess.MainModule.FileName} PID {currentProcess.Id}).  Press enter to continue...");
                    Console.ReadLine();
                    break;
            }

#if FEATURE_GET_COMMANDLINE
            ErrorUtilities.VerifyThrowArgumentLength(commandLine, "commandLine");
#endif

            ExitType exitType = ExitType.Success;

            ConsoleCancelEventHandler cancelHandler = Console_CancelKeyPress;
            try
            {
#if (!STANDALONEBUILD)
                // Enable CodeMarkers for MSBuild.exe
                CodeMarkers.Instance.InitPerformanceDll(CodeMarkerApp.MSBUILDPERF,  String.Format(CultureInfo.InvariantCulture, @"Software\Microsoft\MSBuild\{0}", MSBuildConstants.CurrentProductVersion));
#endif
#if MSBUILDENABLEVSPROFILING 
                string startMSBuildExe = String.Format(CultureInfo.CurrentCulture, "Running MSBuild.exe with command line {0}", commandLine);
                DataCollection.CommentMarkProfile(8800, startMSBuildExe);
#endif
                Console.CancelKeyPress += cancelHandler;

                // check the operating system the code is running on
                VerifyThrowSupportedOS();

                // Setup the console UI.
                SetConsoleUI();

                // reset the application state for this new build
                ResetBuildState();

                // process the detected command line switches -- gather build information, take action on non-build switches, and
                // check for non-trivial errors
                string projectFile = null;
                string[] targets = { };
                string toolsVersion = null;
                Dictionary<string, string> globalProperties = null;
                ILogger[] loggers = { };
                LoggerVerbosity verbosity = LoggerVerbosity.Normal;
                List<DistributedLoggerRecord> distributedLoggerRecords = null;
#if FEATURE_XML_SCHEMA_VALIDATION
                bool needToValidateProject = false;
                string schemaFile = null;
#endif
                int cpuCount = 1;
#if FEATURE_NODE_REUSE
                bool enableNodeReuse = true;
#else
                bool enableNodeReuse = false;
#endif
                TextWriter preprocessWriter = null;
                bool debugger = false;
                bool detailedSummary = false;
                ISet<string> warningsAsErrors = null;
                ISet<string> warningsAsMessages = null;

                CommandLineSwitches switchesFromAutoResponseFile;
                CommandLineSwitches switchesNotFromAutoResponseFile;
                GatherAllSwitches(commandLine, out switchesFromAutoResponseFile, out switchesNotFromAutoResponseFile);

                if (ProcessCommandLineSwitches(
                        switchesFromAutoResponseFile,
                        switchesNotFromAutoResponseFile,
                        ref projectFile,
                        ref targets,
                        ref toolsVersion,
                        ref globalProperties,
                        ref loggers,
                        ref verbosity,
                        ref distributedLoggerRecords,
#if FEATURE_XML_SCHEMA_VALIDATION
                        ref needToValidateProject,
                        ref schemaFile,
#endif
                        ref cpuCount,
#if FEATURE_NODE_REUSE
                        ref enableNodeReuse,
#endif
                        ref preprocessWriter,
                        ref debugger,
                        ref detailedSummary,
                        ref warningsAsErrors,
                        ref warningsAsMessages,
                        recursing: false
                        ))
                {
                    // Unfortunately /m isn't the default, and we are not yet brave enough to make it the default.
                    // However we want to give a hint to anyone who is building single proc without realizing it that there
                    // is a better way.
                    if (cpuCount == 1 && FileUtilities.IsSolutionFilename(projectFile) && verbosity > LoggerVerbosity.Minimal)
                    {
                        Console.WriteLine(ResourceUtilities.FormatResourceString("PossiblyOmittedMaxCPUSwitch"));
                    }
                    if (preprocessWriter != null || debugger)
                    {
                        // Indicate to the engine that it can NOT toss extraneous file content: we want to 
                        // see that in preprocessing/debugging
                        Environment.SetEnvironmentVariable("MSBUILDLOADALLFILESASWRITEABLE", "1");
                    }

                    DateTime t1 = DateTime.Now;

                    // If the primary file passed to MSBuild is a .binlog file, play it back into passed loggers
                    // as if a build is happening
                    if (FileUtilities.IsBinaryLogFilename(projectFile))
                    {
                        ReplayBinaryLog(projectFile, loggers, distributedLoggerRecords, cpuCount);
                    }
                    else // regular build
                    {
#if !STANDALONEBUILD
                    if (Environment.GetEnvironmentVariable("MSBUILDOLDOM") != "1")
#endif
                        {
                            // if everything checks out, and sufficient information is available to start building
                            if (!BuildProject(projectFile, targets, toolsVersion, globalProperties, loggers, verbosity, distributedLoggerRecords.ToArray(),
#if FEATURE_XML_SCHEMA_VALIDATION
                            needToValidateProject, schemaFile,
#endif
                            cpuCount, enableNodeReuse, preprocessWriter, debugger, detailedSummary, warningsAsErrors, warningsAsMessages))
                            {
                                exitType = ExitType.BuildError;
                            }
                        }
#if !STANDALONEBUILD
                    else
                    {
                        exitType = OldOMBuildProject(exitType, projectFile, targets, toolsVersion, globalProperties, loggers, verbosity, needToValidateProject, schemaFile, cpuCount);
                    }
#endif
                    } // end of build

                    DateTime t2 = DateTime.Now;

                    TimeSpan elapsedTime = t2.Subtract(t1);

                    string timerOutputFilename = Environment.GetEnvironmentVariable("MSBUILDTIMEROUTPUTS");

                    if (!String.IsNullOrEmpty(timerOutputFilename))
                    {
                        AppendOutputFile(timerOutputFilename, (long)elapsedTime.TotalMilliseconds);
                    }
                }
                else
                {
                    // if there was no need to start the build e.g. because /help was triggered
                    // do nothing
                }
            }
            /**********************************************************************************************************************
             * WARNING: Do NOT add any more catch blocks below! Exceptions should be caught as close to their point of origin as
             * possible, and converted into one of the known exceptions. The code that causes an exception best understands the
             * reason for the exception, and only that code can provide the proper error message. We do NOT want to display
             * messages from unknown exceptions, because those messages are most likely neither localized, nor composed in the
             * canonical form with the correct prefix.
             *********************************************************************************************************************/
            // handle switch errors
            catch (CommandLineSwitchException e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine();
                // prompt user to display help for proper switch usage
                ShowHelpPrompt();

                exitType = ExitType.SwitchError;
            }
            // handle configuration exceptions: problems reading toolset information from msbuild.exe.config or the registry
            catch (InvalidToolsetDefinitionException e)
            {
                // Brief prefix to indicate that it's a configuration failure, and provide the "error" indication
                Console.WriteLine(ResourceUtilities.FormatResourceString("ConfigurationFailurePrefixNoErrorCode", e.ErrorCode, e.Message));

                exitType = ExitType.InitializationError;
            }
            // handle initialization failures
            catch (InitializationException e)
            {
                Console.WriteLine(e.Message);

                exitType = ExitType.InitializationError;
            }
            // handle polite logger failures: don't dump the stack or trigger watson for these
            catch (LoggerException e)
            {
                // display the localized message from the outer exception in canonical format
                if (null != e.ErrorCode)
                {
                    // Brief prefix to indicate that it's a logger failure, and provide the "error" indication
                    Console.WriteLine(ResourceUtilities.FormatResourceString("LoggerFailurePrefixNoErrorCode", e.ErrorCode, e.Message));
                }
                else
                {
                    // Brief prefix to indicate that it's a logger failure, adding a generic error code to make sure
                    // there's something for the user to look up in the documentation
                    Console.WriteLine(ResourceUtilities.FormatResourceString("LoggerFailurePrefixWithErrorCode", e.Message));
                }

                if (null != e.InnerException)
                {
                    // write out exception details -- don't bother triggering Watson, because most of these exceptions will be coming
                    // from buggy loggers written by users
                    Console.WriteLine(e.InnerException.ToString());
                }

                exitType = ExitType.LoggerAbort;
            }
            // handle logger failures (logger bugs)
            catch (InternalLoggerException e)
            {
                if (!e.InitializationException)
                {
                    // display the localized message from the outer exception in canonical format
                    Console.WriteLine("MSBUILD : error " + e.ErrorCode + ": " + e.Message);
#if DEBUG
                    Console.WriteLine("This is an unhandled exception from a logger -- PLEASE OPEN A BUG AGAINST THE LOGGER OWNER.");
#endif
                    // write out exception details -- don't bother triggering Watson, because most of these exceptions will be coming
                    // from buggy loggers written by users
                    Console.WriteLine(e.InnerException.ToString());

                    exitType = ExitType.LoggerFailure;
                }
                else
                {
                    Console.WriteLine("MSBUILD : error " + e.ErrorCode + ": " + e.Message +
                        (e.InnerException != null ? " " + e.InnerException.Message : ""));
                    exitType = ExitType.InitializationError;
                }
            }
            catch (BuildAbortedException e)
            {
                Console.WriteLine("MSBUILD : error " + e.ErrorCode + ": " + e.Message +
                                (e.InnerException != null ? " " + e.InnerException.Message : String.Empty));

                exitType = ExitType.Unexpected;
            }
            // handle fatal errors
            catch (Exception e)
            {
                // display a generic localized message for the user
                Console.WriteLine("{0}\r\n{1}", AssemblyResources.GetString("FatalError"), e.ToString());
#if DEBUG
                Console.WriteLine("This is an unhandled exception in MSBuild Engine -- PLEASE OPEN A BUG AGAINST THE MSBUILD TEAM.\r\n{0}", e.ToString());
#endif
                // rethrow, in case Watson is enabled on the machine -- if not, the CLR will write out exception details
                // allow the build lab to set an env var to avoid jamming the build
                if (Environment.GetEnvironmentVariable("MSBUILDDONOTLAUNCHDEBUGGER") != "1")
                {
                    throw;
                }
            }
            finally
            {
                s_buildComplete.Set();
                Console.CancelKeyPress -= cancelHandler;

                // Wait for any pending cancel, so that we get any remaining messages
                s_cancelComplete.WaitOne();
#if (!STANDALONEBUILD)
                // Turn off codemarkers
                CodeMarkers.Instance.UninitializePerformanceDLL(CodeMarkerApp.MSBUILDPERF);
#endif
            }
            /**********************************************************************************************************************
             * WARNING: Do NOT add any more catch blocks above!
             *********************************************************************************************************************/

            return exitType;
        }