예제 #1
0
        public void TestMSBuildForwardPropertiesFromChild()
        {
            Environment.SetEnvironmentVariable("MSBuildForwardPropertiesFromChild", null);
            Engine childEngine = new Engine(new BuildPropertyGroup(), new ToolsetDefinitionLocations(), 3, true, 3, string.Empty, string.Empty);
            string[] propertiesToSerialize = childEngine.PropertyListToSerialize;
            Assert.IsNull(propertiesToSerialize, "Expected propertiesToSerialize to be null");
	    childEngine.Shutdown();
            
	    Environment.SetEnvironmentVariable("MSBuildForwardPropertiesFromChild", string.Empty);
            childEngine = new Engine(new BuildPropertyGroup(), new ToolsetDefinitionLocations(), 3, true, 3, string.Empty, string.Empty);
            propertiesToSerialize = childEngine.PropertyListToSerialize;
            Assert.IsNull(propertiesToSerialize, "Expected propertiesToSerialize to be null");
            childEngine.Shutdown();

             Environment.SetEnvironmentVariable("MSBuildForwardPropertiesFromChild", "Platform;Configuration");
             childEngine = new Engine(new BuildPropertyGroup(), new ToolsetDefinitionLocations(), 3, true, 3, string.Empty, string.Empty);
             propertiesToSerialize = childEngine.PropertyListToSerialize;
             Assert.IsTrue(string.Compare(propertiesToSerialize[0], "Platform") == 0);
             Assert.IsTrue(string.Compare(propertiesToSerialize[1], "Configuration") == 0);
             Assert.IsTrue(propertiesToSerialize.Length == 2);
             childEngine.Shutdown();

             Environment.SetEnvironmentVariable("MSBuildForwardPropertiesFromChild", "Platform;;;;;;;;;;Configuration");
             childEngine = new Engine(new BuildPropertyGroup(), new ToolsetDefinitionLocations(), 3, true, 3, string.Empty, string.Empty);
             propertiesToSerialize = childEngine.PropertyListToSerialize;
             Assert.IsTrue(string.Compare(propertiesToSerialize[0], "Platform") == 0);
             Assert.IsTrue(string.Compare(propertiesToSerialize[1], "Configuration") == 0);
             Assert.IsTrue(propertiesToSerialize.Length == 2);
             childEngine.Shutdown();

             Environment.SetEnvironmentVariable("MSBuildForwardPropertiesFromChild", "Platform;");
             childEngine = new Engine(new BuildPropertyGroup(), new ToolsetDefinitionLocations(), 3, true, 3, string.Empty, string.Empty);
             propertiesToSerialize = childEngine.PropertyListToSerialize;
             Assert.IsTrue(string.Compare(propertiesToSerialize[0], "Platform") == 0);
             Assert.IsTrue(propertiesToSerialize.Length == 1);
             childEngine.Shutdown();

             Environment.SetEnvironmentVariable("MSBuildForwardPropertiesFromChild", "Platform");
             childEngine = new Engine(new BuildPropertyGroup(), new ToolsetDefinitionLocations(), 3, true, 3, string.Empty, string.Empty);
             propertiesToSerialize = childEngine.PropertyListToSerialize;
             Assert.IsTrue(string.Compare(propertiesToSerialize[0], "Platform") == 0);
             Assert.IsTrue(propertiesToSerialize.Length == 1);
             childEngine.Shutdown();
             
            Environment.SetEnvironmentVariable("MSBuildForwardPropertiesFromChild", ";Platform");
             childEngine = new Engine(new BuildPropertyGroup(), new ToolsetDefinitionLocations(), 3, true, 3, string.Empty, string.Empty);
             propertiesToSerialize = childEngine.PropertyListToSerialize;
             Assert.IsTrue(string.Compare(propertiesToSerialize[0], "Platform") == 0);
             Assert.IsTrue(propertiesToSerialize.Length == 1);
             childEngine.Shutdown();


             Environment.SetEnvironmentVariable("MSBuildForwardPropertiesFromChild", ";Platform;");
             childEngine = new Engine(new BuildPropertyGroup(), new ToolsetDefinitionLocations(), 3, true, 3, string.Empty, string.Empty);
             propertiesToSerialize = childEngine.PropertyListToSerialize;
             Assert.IsTrue(string.Compare(propertiesToSerialize[0], "Platform") == 0);
             Assert.IsTrue(propertiesToSerialize.Length == 1);
             childEngine.Shutdown();
        }
예제 #2
0
        static void Main(string[] args)
        {                      
            // We need to tell MSBuild where msbuild.exe is, so it can launch child nodes
            string parameters = @"MSBUILDLOCATION=" + System.Environment.GetFolderPath(System.Environment.SpecialFolder.System) + @"\..\Microsoft.NET\Framework\v3.5";
            
            // We need to tell MSBuild whether nodes should hang around for 60 seconds after the build is done in case they are needed again
            bool nodeReuse = true; // e.g.
            if (!nodeReuse)
            {
                parameters += ";NODEREUSE=false";
            }

            // We need to tell MSBuild the maximum number of nodes to use. It is usually fastest to pick about the same number as you have CPU cores
            int maxNodeCount = 3; // e.g.

            // Create the engine with this information
            Engine buildEngine = new Engine(null, ToolsetDefinitionLocations.Registry | ToolsetDefinitionLocations.ConfigurationFile, maxNodeCount, parameters);

            // Create a file logger with a matching forwarding logger, e.g.
            FileLogger fileLogger = new FileLogger();
            fileLogger.Verbosity = LoggerVerbosity.Detailed;
            Assembly engineAssembly = Assembly.GetAssembly(typeof(Engine));
            string loggerAssemblyName = engineAssembly.GetName().FullName;
            LoggerDescription fileLoggerForwardingLoggerDescription = new LoggerDescription("Microsoft.Build.BuildEngine.ConfigurableForwardingLogger", loggerAssemblyName, null, String.Empty, LoggerVerbosity.Detailed);

            // Create a regular console logger too, e.g.
            ConsoleLogger logger = new ConsoleLogger();
            logger.Verbosity = LoggerVerbosity.Normal;

            // Register all of these loggers
            buildEngine.RegisterDistributedLogger(fileLogger, fileLoggerForwardingLoggerDescription);
            buildEngine.RegisterLogger(logger);

            // Do a build
            buildEngine.BuildProjectFile("root.proj");

            // Finish cleanly
            buildEngine.Shutdown();
        }
예제 #3
0
파일: Node.cs 프로젝트: nikson/msbuild
        private void NodeLocalEngineLoop()
        {
            buildInProgress = true;

            // Create a logging service for this build request
            localEngine =
                new Engine(parentGlobalProperties, toolsetSearchLocations, 1 /* cpus */, true /* child node */, this.nodeId, parentStartupDirectory, null);
            localEngine.Router.ChildMode = true;
            localEngine.Router.ParentNode = this;

            this.outProcLoggingService = new EngineLoggingServicesOutProc(this, localEngine.FlushRequestEvent);

            if (nodeLoggers.Length != 0)
            {
                foreach (LoggerDescription loggerDescription in nodeLoggers)
                {
                    IForwardingLogger newLogger = null;
                    bool exitedDueToError = true;
                    try
                    {
                        newLogger = loggerDescription.CreateForwardingLogger();
                        // Check if the class was not found in the assembly
                        if (newLogger == null)
                        {
                            InternalLoggerException.Throw(null, null, "FatalErrorWhileInitializingLogger", true, loggerDescription.Name);
                        }
                        newLogger.Verbosity = loggerDescription.Verbosity;
                        newLogger.Parameters = loggerDescription.LoggerSwitchParameters;
                        newLogger.NodeId = nodeId;
                        EventRedirector newRedirector = new EventRedirector(loggerDescription.LoggerId, outProcLoggingService);
                        newLogger.BuildEventRedirector = newRedirector;
                        exitedDueToError = false;
                    }
                    // Polite logger failure
                    catch (LoggerException e)
                    {
                        ReportUnhandledError(e);
                    }
                    // Logger class was not found
                    catch (InternalLoggerException e)
                    {
                        ReportUnhandledError(e);
                    }
                    catch (Exception e)
                    {
                        // Wrap the exception in a InternalLoggerException and send it to the parent node
                        string errorCode;
                        string helpKeyword;
                        string message = ResourceUtilities.FormatResourceString(out errorCode, out helpKeyword, "FatalErrorWhileInitializingLogger", loggerDescription.Name);
                        ReportUnhandledError(new InternalLoggerException(message, e, null, errorCode, helpKeyword, true));
                    }

                    // If there was a failure registering loggers, null out the engine pointer
                    if (exitedDueToError)
                    {
                        localEngine = null;
                        return;
                    }

                    localEngine.RegisterLogger(newLogger);
                }

                localEngine.ExternalLoggingServices = outProcLoggingService;
            }

            // Hook up logging service to forward all events to the central engine if necessary
            if (centralizedLogging)
            {
                if (nodeLoggers.Length != 0)
                {
                    localEngine.LoggingServices.ForwardingService = outProcLoggingService;
                    localEngine.ExternalLoggingServices = outProcLoggingService;
                }
                else
                {
                    localEngine.LoggingServices = outProcLoggingService;
                }
            }

            localEngine.LoggingServices.OnlyLogCriticalEvents = this.logOnlyCriticalEvents;

            if (!useBreadthFirstTraversal)
            {
                localEngine.PostEngineCommand(new ChangeTraversalTypeCommand(useBreadthFirstTraversal, true));
            }

            // Post all the requests that passed in while the engine was being constructed
            // into the engine queue
            lock (buildRequests)
            {
                while (buildRequests.Count != 0)
                {
                    BuildRequest buildRequest = buildRequests.Dequeue();
                    localEngine.PostBuildRequest(buildRequest);
                }
            }

            try
            {
                // If there are forwarding loggers registered - generate a custom  build started
                if (nodeLoggers.Length > 0)
                {
                    localEngine.LoggingServices.LogBuildStarted(EngineLoggingServicesInProc.CENTRAL_ENGINE_EVENTSOURCE);
                    localEngine.LoggingServices.ProcessPostedLoggingEvents();
                }

                // Trigger the actual build if shutdown was not called while the engine was being initialized
                if (!nodeShutdown)
                {
                    localEngine.EngineBuildLoop(null);
                }
            }
            catch (Exception e)
            {
                // Unhandled exception during execution. The node has to be shutdown.
                ReportUnhandledError(e);
            }
            finally
            {
                if (localEngine != null)
                {
                    // Flush all the messages associated before shutting down
                    localEngine.LoggingServices.ProcessPostedLoggingEvents();

                    NodeManager nodeManager = localEngine.NodeManager;

                    // If the local engine is already shutting down, the TEM will be nulled out
                    if (nodeManager.TaskExecutionModule != null && nodeManager.TaskExecutionModule.TaskExecutionTime != 0)
                    {
                        TimeSpan taskTimeSpan = new TimeSpan(localEngine.NodeManager.TaskExecutionModule.TaskExecutionTime);
                        totalTaskTime = (int)taskTimeSpan.TotalMilliseconds;
                    }
                    localEngine.Shutdown();
                }
                // Flush all the events to the parent engine
                outProcLoggingService.ProcessPostedLoggingEvents();
                // Indicate that the node logger thread should exit
                exitNodeEvent.Set();
            }
        }
예제 #4
0
        public void BuildProjectFilesInParallel2()
        {
            string[] fileNames = new string[10];
            string[] fileNames2 = new string[10];
            string[] fileNamesLeafs = new string[10];
            string[] childTraversals = new string[10];
            string parentTraversal = TraversalProjectFile("CTrav");
            string traversalProject = TraversalProjectFile("ABC");

            string[][] targetNamesPerProject = new string[fileNames.Length][];
            IDictionary[] targetOutPutsPerProject = new IDictionary[fileNames.Length];
            BuildPropertyGroup[] globalPropertiesPerProject = new BuildPropertyGroup[fileNames.Length];
            
            string[] tempfilesToDelete = new string[fileNames.Length];
            string[] tempfilesToDelete2 = new string[fileNames.Length];
            string[] tempfilesToDelete3 = new string[fileNames.Length];
            string[] tempfilesToDelete4 = new string[fileNames.Length];
            Engine engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 4, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory);
            try
            {
                for (int i = 0; i < fileNames.Length; i++)
                {
                    string[] ProjectFiles1 = CreateGlobalPropertyProjectFileWithExtension("ABC");
                    string[] ProjectFiles2 = CreateGlobalPropertyProjectFileWithExtension("DEF");
                    string[] FileNamesLeafs = CreateGlobalPropertyProjectFileWithExtension("LEAF");
                    string[] ChildTraversals = CreateSingleProjectTraversalFileWithExtension(FileNamesLeafs[0],"CTrav");

                    fileNames[i] = ProjectFiles1[0];
                    fileNames2[i] = ProjectFiles2[0];
                    fileNamesLeafs[i] = FileNamesLeafs[0];
                    childTraversals[i] = ChildTraversals[0];
                    
                    tempfilesToDelete[i] = ProjectFiles1[1];
                    tempfilesToDelete2[i] = ProjectFiles2[1];
                    tempfilesToDelete3[i] = FileNamesLeafs[1];
                    tempfilesToDelete4[i] = ChildTraversals[1];
                    targetNamesPerProject[i] = new string[] { "Build" };
                }


                // Try building a traversal project that had other traversals
                
                engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal));
                engine.BuildProjectFile(parentTraversal, new string[] { "Build" }, new BuildPropertyGroup(), null, BuildSettings.None, "3.5");
                engine.Shutdown();

                 engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 4, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory);
                engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal));
                // Try building the same traversal project on the same engine one after another
                engine.BuildProjectFile(traversalProject);
                engine.BuildProjectFile(traversalProject);
                engine.Shutdown();

                // Try building the same set of project files on the same engine one after another
                engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 4, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory);
                engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal));
                engine.BuildProjectFiles(fileNames, targetNamesPerProject, globalPropertiesPerProject, targetOutPutsPerProject, BuildSettings.None, new string[fileNames.Length]);
                engine.BuildProjectFiles(fileNames, targetNamesPerProject, globalPropertiesPerProject, targetOutPutsPerProject, BuildSettings.None, new string[fileNames.Length]);
                engine.Shutdown();

                // Try building a set of project files, then the same set as a traversal on the same engine
                engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 4, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory);
                engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal));
                engine.BuildProjectFiles(fileNames2, targetNamesPerProject, globalPropertiesPerProject, targetOutPutsPerProject, BuildSettings.None, new string[fileNames.Length]);
                engine.BuildProjectFile(traversalProject);
                engine.Shutdown();


                // Try building a traversal, then the same files which are in the traversal in parallel on the same engine
                engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 4, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory);
                engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal));
                engine.BuildProjectFile(traversalProject);
                engine.BuildProjectFiles(fileNames2, targetNamesPerProject, globalPropertiesPerProject, targetOutPutsPerProject, BuildSettings.None, new string[fileNames.Length]);
                engine.Shutdown();
                /* Do the same as above using single proc */

                // Try building the same traversal project on the same engine one after another
                engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 1, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory);
                engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal));
                engine.BuildProjectFile(traversalProject);
                engine.BuildProjectFile(traversalProject);
                engine.Shutdown();

                // Try building the same set of project files on the same engine one after another
                engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 1, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory);
                engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal));
                engine.BuildProjectFiles(fileNames, targetNamesPerProject, globalPropertiesPerProject, targetOutPutsPerProject, BuildSettings.None, new string[fileNames.Length]);
                engine.BuildProjectFiles(fileNames, targetNamesPerProject, globalPropertiesPerProject, targetOutPutsPerProject, BuildSettings.None, new string[fileNames.Length]);
                engine.Shutdown();

                // Try building a set of project files, then the same set as a traversal on the same engine
                engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 1, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory);
                engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal));
                engine.BuildProjectFiles(fileNames2, targetNamesPerProject, globalPropertiesPerProject, targetOutPutsPerProject, BuildSettings.None, new string[fileNames.Length]);
                engine.BuildProjectFile(traversalProject);
                engine.Shutdown();

                // Try building a traversal, then the same files which are in the traversal in parallel on the same engine
                engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 4, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory);
                engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal));
                engine.BuildProjectFile(traversalProject);
                engine.BuildProjectFiles(fileNames2, targetNamesPerProject, globalPropertiesPerProject, targetOutPutsPerProject, BuildSettings.None, new string[fileNames.Length]);
            }
            finally
            {
                engine.Shutdown();
                for (int i = 0; i < fileNames.Length; i++)
                {
                    File.Delete(fileNames[i]);
                    File.Delete(fileNames2[i]);
                    File.Delete(fileNamesLeafs[i]);
                    File.Delete(childTraversals[i]);
                    File.Delete(tempfilesToDelete[i]);
                    File.Delete(tempfilesToDelete2[i]);
                    File.Delete(tempfilesToDelete3[i]);
                    File.Delete(tempfilesToDelete4[i]);
                }
                File.Delete(traversalProject);
            }
        }
예제 #5
0
        public void BuildProjectFilesInParallel()
        {

            //Gets the currently loaded assembly in which the specified class is defined
            Assembly engineAssembly = Assembly.GetAssembly(typeof(Engine));
            string loggerClassName = "Microsoft.Build.BuildEngine.ConfigurableForwardingLogger";
            string loggerAssemblyName = engineAssembly.GetName().FullName;
            LoggerDescription forwardingLoggerDescription = new LoggerDescription(loggerClassName, loggerAssemblyName, null, null, LoggerVerbosity.Normal);

            string[] fileNames = new string[10];
            string traversalProject = TraversalProjectFile("ABC");
            string[][] targetNamesPerProject = new string[fileNames.Length][];
            IDictionary[] targetOutPutsPerProject = new IDictionary[fileNames.Length];
            BuildPropertyGroup[] globalPropertiesPerProject = new BuildPropertyGroup[fileNames.Length];
            string[] tempfilesToDelete = new string[fileNames.Length];
            Engine engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 4, "msbuildlocation="+AppDomain.CurrentDomain.BaseDirectory);
            engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal));
            try
            {
                for (int i = 0; i < fileNames.Length; i++)
                {
                    string[] ProjectFiles1 = CreateGlobalPropertyProjectFileWithExtension("ABC");
                    fileNames[i] = ProjectFiles1[0];
                    tempfilesToDelete[i] = ProjectFiles1[1];
                    targetNamesPerProject[i] = new string[] { "Build" };
                }

                // Test building a traversal
              
                engine.BuildProjectFile(traversalProject);
                engine.Shutdown();
                
                // Test building the same set of files in parallel
                Console.Out.WriteLine("1:"+Process.GetCurrentProcess().MainModule.FileName);
                Console.Out.WriteLine("2:" + AppDomain.CurrentDomain.BaseDirectory);
                engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 4, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory);
                engine.RegisterDistributedLogger(new ConsoleLogger(LoggerVerbosity.Normal), forwardingLoggerDescription);
                engine.BuildProjectFiles(fileNames, targetNamesPerProject, globalPropertiesPerProject, targetOutPutsPerProject, BuildSettings.None, new string[fileNames.Length]);
                engine.Shutdown();

                // Do the same using singleproc
                engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 4, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory);
                engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal));
                engine.BuildProjectFile(traversalProject);
                engine.Shutdown();

                engine = new Engine(null, ToolsetDefinitionLocations.ConfigurationFile | ToolsetDefinitionLocations.Registry, 1, "msbuildlocation="+ AppDomain.CurrentDomain.BaseDirectory);
                engine.RegisterLogger(new ConsoleLogger(LoggerVerbosity.Normal));
                engine.BuildProjectFiles(fileNames, targetNamesPerProject, globalPropertiesPerProject, targetOutPutsPerProject, BuildSettings.None, new string[fileNames.Length]);

            }
            finally
            {
                engine.Shutdown();
                for (int i = 0; i < fileNames.Length; i++)
                {
                    File.Delete(fileNames[i]);
                    File.Delete(tempfilesToDelete[i]);
                }
                File.Delete(traversalProject);
            }
        }
예제 #6
0
        private void NodeLocalEngineLoop()
        {
            buildInProgress = true;

            // Create a logging service for this build request
            localEngine =
                new Engine(parentGlobalProperties, toolsetSearchLocations, 1 /* cpus */, true /* child node */, this.nodeId, parentStartupDirectory, null);
            localEngine.Router.ChildMode  = true;
            localEngine.Router.ParentNode = this;

            this.outProcLoggingService = new EngineLoggingServicesOutProc(this, localEngine.FlushRequestEvent);

            if (nodeLoggers.Length != 0)
            {
                foreach (LoggerDescription loggerDescription in nodeLoggers)
                {
                    IForwardingLogger newLogger = null;
                    bool exitedDueToError       = true;
                    try
                    {
                        newLogger = loggerDescription.CreateForwardingLogger();
                        // Check if the class was not found in the assembly
                        if (newLogger == null)
                        {
                            InternalLoggerException.Throw(null, null, "FatalErrorWhileInitializingLogger", true, loggerDescription.Name);
                        }
                        newLogger.Verbosity  = loggerDescription.Verbosity;
                        newLogger.Parameters = loggerDescription.LoggerSwitchParameters;
                        newLogger.NodeId     = nodeId;
                        EventRedirector newRedirector = new EventRedirector(loggerDescription.LoggerId, outProcLoggingService);
                        newLogger.BuildEventRedirector = newRedirector;
                        exitedDueToError = false;
                    }
                    // Polite logger failure
                    catch (LoggerException e)
                    {
                        ReportUnhandledError(e);
                    }
                    // Logger class was not found
                    catch (InternalLoggerException e)
                    {
                        ReportUnhandledError(e);
                    }
                    catch (Exception e)
                    {
                        // Wrap the exception in a InternalLoggerException and send it to the parent node
                        string errorCode;
                        string helpKeyword;
                        string message = ResourceUtilities.FormatResourceString(out errorCode, out helpKeyword, "FatalErrorWhileInitializingLogger", loggerDescription.Name);
                        ReportUnhandledError(new InternalLoggerException(message, e, null, errorCode, helpKeyword, true));
                    }

                    // If there was a failure registering loggers, null out the engine pointer
                    if (exitedDueToError)
                    {
                        localEngine = null;
                        return;
                    }

                    localEngine.RegisterLogger(newLogger);
                }

                localEngine.ExternalLoggingServices = outProcLoggingService;
            }

            // Hook up logging service to forward all events to the central engine if necessary
            if (centralizedLogging)
            {
                if (nodeLoggers.Length != 0)
                {
                    localEngine.LoggingServices.ForwardingService = outProcLoggingService;
                    localEngine.ExternalLoggingServices           = outProcLoggingService;
                }
                else
                {
                    localEngine.LoggingServices = outProcLoggingService;
                }
            }

            localEngine.LoggingServices.OnlyLogCriticalEvents = this.logOnlyCriticalEvents;

            if (!useBreadthFirstTraversal)
            {
                localEngine.PostEngineCommand(new ChangeTraversalTypeCommand(useBreadthFirstTraversal, true));
            }

            // Post all the requests that passed in while the engine was being constructed
            // into the engine queue
            lock (buildRequests)
            {
                while (buildRequests.Count != 0)
                {
                    BuildRequest buildRequest = buildRequests.Dequeue();
                    localEngine.PostBuildRequest(buildRequest);
                }
            }

            try
            {
                // If there are forwarding loggers registered - generate a custom  build started
                if (nodeLoggers.Length > 0)
                {
                    localEngine.LoggingServices.LogBuildStarted(EngineLoggingServicesInProc.CENTRAL_ENGINE_EVENTSOURCE);
                    localEngine.LoggingServices.ProcessPostedLoggingEvents();
                }

                // Trigger the actual build if shutdown was not called while the engine was being initialized
                if (!nodeShutdown)
                {
                    localEngine.EngineBuildLoop(null);
                }
            }
            catch (Exception e)
            {
                // Unhandled exception during execution. The node has to be shutdown.
                ReportUnhandledError(e);
            }
            finally
            {
                if (localEngine != null)
                {
                    // Flush all the messages associated before shutting down
                    localEngine.LoggingServices.ProcessPostedLoggingEvents();

                    NodeManager nodeManager = localEngine.NodeManager;

                    // If the local engine is already shutting down, the TEM will be nulled out
                    if (nodeManager.TaskExecutionModule != null && nodeManager.TaskExecutionModule.TaskExecutionTime != 0)
                    {
                        TimeSpan taskTimeSpan = new TimeSpan(localEngine.NodeManager.TaskExecutionModule.TaskExecutionTime);
                        totalTaskTime = (int)taskTimeSpan.TotalMilliseconds;
                    }
                    localEngine.Shutdown();
                }
                // Flush all the events to the parent engine
                outProcLoggingService.ProcessPostedLoggingEvents();
                // Indicate that the node logger thread should exit
                exitNodeEvent.Set();
            }
        }