/// <summary> /// Instantiates a new MSBuild process acting as a child node. /// </summary> public bool CreateNode(int nodeId, INodePacketFactory factory, NodeConfiguration configuration) { throw new NotImplementedException("Use the other overload of CreateNode instead"); }
/// <summary> /// Requests that a node be created on the specified machine. /// </summary> /// <param name="nodeId">The id of the node to create.</param> /// <param name="factory">The factory to use to create packets from this node.</param> /// <param name="configuration">The configuration for the node.</param> public bool CreateNode(int nodeId, INodePacketFactory factory, NodeConfiguration configuration) { ErrorUtilities.VerifyThrow(nodeId != InvalidInProcNodeId, "Cannot create in-proc node."); // Attempt to get the operating environment semaphore if requested. if (_componentHost.BuildParameters.SaveOperatingEnvironment) { // We can only create additional in-proc nodes if we have decided not to save the operating environment. This is the global // DTAR case in Visual Studio, but other clients might enable this as well under certain special circumstances. ErrorUtilities.VerifyThrow(_inProcNodeOwningOperatingEnvironment == null, "Unexpected non-null in-proc node semaphore."); // Blend.exe v4.x or earlier launches two nodes that co-own the same operating environment // and they will not patch this var p = Process.GetCurrentProcess(); { // This should be reasonably sufficient to assume MS Expression Blend 4 or earlier if ((FileUtilities.CurrentExecutableName.Equals("Blend", StringComparison.OrdinalIgnoreCase)) && (p.MainModule.FileVersionInfo.OriginalFilename.Equals("Blend.exe", StringComparison.OrdinalIgnoreCase)) && (p.MainModule.FileVersionInfo.ProductMajorPart < 5)) { _exclusiveOperatingEnvironment = false; } } if (Environment.GetEnvironmentVariable("MSBUILDINPROCENVCHECK") == "1") { _exclusiveOperatingEnvironment = true; } if (_exclusiveOperatingEnvironment) { _inProcNodeOwningOperatingEnvironment = new Semaphore(1, 1, "MSBuildIPN_" + Process.GetCurrentProcess().Id); if (!_inProcNodeOwningOperatingEnvironment.WaitOne(0)) { // Can't take the operating environment. return false; } } } // If it doesn't already exist, create it. if (_inProcNode == null) { if (!InstantiateNode(factory)) { return false; } } _inProcNodeEndpoint.SendData(configuration); _inProcNodeId = nodeId; return true; }
/// <summary> /// Creates a node on an available NodeProvider, if any.. /// </summary> /// <param name="configuration">The configuration to use for the remote node.</param> /// <returns>A NodeInfo describing the node created, or null if none could be created.</returns> public NodeInfo CreateNode(NodeConfiguration configuration, NodeAffinity nodeAffinity) { throw new NotSupportedException("not used"); }
public NodeInfo CreateNode(NodeConfiguration configuration, NodeAffinity nodeAffinity) { throw new NotSupportedException("not used"); }
/// <summary> /// Instantiates a new MSBuild process acting as a child node. /// </summary> public bool CreateNode(int nodeId, INodePacketFactory factory, NodeConfiguration configuration) { ErrorUtilities.VerifyThrowArgumentNull(factory, "factory"); if (_nodeContexts.Count == ComponentHost.BuildParameters.MaxNodeCount) { ErrorUtilities.ThrowInternalError("All allowable nodes already created ({0}).", _nodeContexts.Count); return false; } // Start the new process. We pass in a node mode with a node number of 1, to indicate that we // want to start up just a standard MSBuild out-of-proc node. // Note: We need to always pass /nodeReuse to ensure the value for /nodeReuse from msbuild.rsp // (next to msbuild.exe) is ignored. string commandLineArgs = ComponentHost.BuildParameters.EnableNodeReuse ? "/nologo /nodemode:1 /nodeReuse:true" : "/nologo /nodemode:1 /nodeReuse:false"; // Make it here. CommunicationsUtilities.Trace("Starting to acquire a new or existing node to establish node ID {0}...", nodeId); NodeContext context = GetNode(null, commandLineArgs, nodeId, factory, NodeProviderOutOfProc.GetHostHandshake(ComponentHost.BuildParameters.EnableNodeReuse), NodeProviderOutOfProc.GetClientHandshake(), NodeContextTerminated); if (null != context) { _nodeContexts[nodeId] = context; // Start the asynchronous read. context.BeginAsyncPacketRead(); // Configure the node. context.SendData(configuration); return true; } throw new BuildAbortedException(ResourceUtilities.FormatResourceString("CouldNotConnectToMSBuildExe", ComponentHost.BuildParameters.NodeExeLocation)); }
/// <summary> /// Requests that a node be created on the specified machine. /// </summary> /// <param name="nodeId">The id of the node to create.</param> /// <param name="factory">The factory to use to create packets from this node.</param> /// <param name="configuration">The configuration for the node.</param> public bool CreateNode(int nodeId, INodePacketFactory factory, NodeConfiguration configuration) { ErrorUtilities.VerifyThrow(nodeId != InvalidInProcNodeId, "Cannot create in-proc node."); // Attempt to get the operating environment semaphore if requested. if (_componentHost.BuildParameters.SaveOperatingEnvironment) { // We can only create additional in-proc nodes if we have decided not to save the operating environment. This is the global // DTAR case in Visual Studio, but other clients might enable this as well under certain special circumstances. ErrorUtilities.VerifyThrow(_inProcNodeOwningOperatingEnvironment == null, "Unexpected non-null in-proc node semaphore."); if (Environment.GetEnvironmentVariable("MSBUILDINPROCENVCHECK") == "1") { _exclusiveOperatingEnvironment = true; } if (_exclusiveOperatingEnvironment) { _inProcNodeOwningOperatingEnvironment = new Semaphore(1, 1, "MSBuildIPN_" + Process.GetCurrentProcess().Id); if (!_inProcNodeOwningOperatingEnvironment.WaitOne(0)) { // Can't take the operating environment. return false; } } } // If it doesn't already exist, create it. if (_inProcNode == null) { if (!InstantiateNode(factory)) { return false; } } _inProcNodeEndpoint.SendData(configuration); _inProcNodeId = nodeId; return true; }
/// <summary> /// Handles the NodeConfiguration packet. /// </summary> private void HandleNodeConfiguration(NodeConfiguration configuration) { // Set the culture. Thread.CurrentThread.CurrentCulture = configuration.BuildParameters.Culture; Thread.CurrentThread.CurrentUICulture = configuration.BuildParameters.UICulture; // Snapshot the initial environment. _savedEnvironment = CommunicationsUtilities.GetEnvironmentVariables(); // Save the current directory. _savedCurrentDirectory = NativeMethodsShared.GetCurrentDirectory(); // Set the node id. _componentHost.BuildParameters.NodeId = configuration.NodeId; _shutdownException = null; // And the AppDomainSetup _componentHost.BuildParameters.AppDomainSetup = configuration.AppDomainSetup; // Declare in-proc _componentHost.BuildParameters.IsOutOfProc = false; // Set the logging exception handler ILoggingService loggingService = _componentHost.LoggingService; loggingService.OnLoggingThreadException += new LoggingExceptionDelegate(OnLoggingThreadException); // Now prep the buildRequestEngine for the build. _loggingContext = new NodeLoggingContext(loggingService, configuration.NodeId, true /* inProcNode */); _buildRequestEngine.OnEngineException += _engineExceptionEventHandler; _buildRequestEngine.OnNewConfigurationRequest += _newConfigurationRequestEventHandler; _buildRequestEngine.OnRequestBlocked += _requestBlockedEventHandler; _buildRequestEngine.OnRequestComplete += _requestCompleteEventHandler; if (_shutdownException != null) { Exception exception; HandleShutdown(out exception); throw exception; } _buildRequestEngine.InitializeForBuild(_loggingContext); // Finally store off this configuration packet. _currentConfiguration = configuration; }
/// <summary> /// Attempts to create a node on the specified machine using the specified provider. /// </summary> /// <param name="nodeProvider">The provider used to create the node.</param> /// <returns>The id of the node created.</returns> private int AttemptCreateNode(INodeProvider nodeProvider, NodeConfiguration nodeConfiguration) { // If no provider was passed in, we obviously can't create a node. if (null == nodeProvider) { ErrorUtilities.ThrowInternalError("No node provider provided."); return InvalidNodeId; } // Are there any free slots on this provider? if (nodeProvider.AvailableNodes == 0) { return InvalidNodeId; } // Assign a global ID to the node we are about to create. int nodeId = InvalidNodeId; if (nodeProvider is NodeProviderInProc) { nodeId = _inprocNodeId; } else { nodeId = _nextNodeId; _nextNodeId++; } NodeConfiguration configToSend = nodeConfiguration.Clone(); configToSend.NodeId = nodeId; // Create the node and add it to our mapping. bool createdNode = nodeProvider.CreateNode(nodeId, this, configToSend); if (!createdNode) { return InvalidNodeId; } _nodeIdToProvider.Add(nodeId, nodeProvider); return nodeId; }
/// <summary> /// Creates a node on an available NodeProvider, if any.. /// </summary> /// <param name="configuration">The configuration to use for the remote node.</param> /// <returns>A NodeInfo describing the node created, or null if none could be created.</returns> public NodeInfo CreateNode(NodeConfiguration configuration, NodeAffinity nodeAffinity) { // We will prefer to make nodes on the "closest" providers first; in-proc, then // out-of-proc, then remote. // When we support distributed build, we will also consider the remote provider. int nodeId = InvalidNodeId; if ((nodeAffinity == NodeAffinity.Any || nodeAffinity == NodeAffinity.InProc) && !_componentHost.BuildParameters.DisableInProcNode) { nodeId = AttemptCreateNode(_inProcNodeProvider, configuration); } if (nodeId == InvalidNodeId && (nodeAffinity == NodeAffinity.Any || nodeAffinity == NodeAffinity.OutOfProc)) { nodeId = AttemptCreateNode(_outOfProcNodeProvider, configuration); } if (nodeId == InvalidNodeId) { return null; } // If we created a node, they should no longer be considered shut down. _nodesShutdown = false; return new NodeInfo(nodeId, _nodeIdToProvider[nodeId].ProviderType); }
/// <summary> /// Handles the NodeConfiguration packet. /// </summary> private void HandleNodeConfiguration(NodeConfiguration configuration) { // Grab the system parameters. _buildParameters = configuration.BuildParameters; _buildParameters.ProjectRootElementCache = s_projectRootElementCache; // Snapshot the current environment _savedEnvironment = CommunicationsUtilities.GetEnvironmentVariables(); // Change to the startup directory try { NativeMethodsShared.SetCurrentDirectory(BuildParameters.StartupDirectory); } catch (DirectoryNotFoundException) { // Somehow the startup directory vanished. This can happen if build was started from a USB Key and it was removed. NativeMethodsShared.SetCurrentDirectory(Environment.SystemDirectory); } // Replicate the environment. First, unset any environment variables set by the previous configuration. if (_currentConfiguration != null) { foreach (string key in _currentConfiguration.BuildParameters.BuildProcessEnvironment.Keys) { Environment.SetEnvironmentVariable(key, null); } } // Now set the new environment foreach (KeyValuePair<string, string> environmentPair in _buildParameters.BuildProcessEnvironment) { Environment.SetEnvironmentVariable(environmentPair.Key, environmentPair.Value); } // We want to make sure the global project collection has the toolsets which were defined on the parent // so that any custom toolsets defined can be picked up by tasks who may use the global project collection but are // executed on the child node. ICollection<Toolset> parentToolSets = _buildParameters.ToolsetProvider.Toolsets; if (parentToolSets != null) { ProjectCollection.GlobalProjectCollection.RemoveAllToolsets(); foreach (Toolset toolSet in parentToolSets) { ProjectCollection.GlobalProjectCollection.AddToolset(toolSet); } } // Set the culture. Thread.CurrentThread.CurrentCulture = _buildParameters.Culture; Thread.CurrentThread.CurrentUICulture = _buildParameters.UICulture; // Get the node ID. _buildParameters.NodeId = configuration.NodeId; _buildParameters.IsOutOfProc = true; // And the AppDomainSetup _buildParameters.AppDomainSetup = configuration.AppDomainSetup; // Set up the logging service. LoggingServiceFactory loggingServiceFactory = new LoggingServiceFactory(LoggerMode.Asynchronous, configuration.NodeId); _componentFactories.ReplaceFactory(BuildComponentType.LoggingService, loggingServiceFactory.CreateInstance); _loggingService = _componentFactories.GetComponent(BuildComponentType.LoggingService) as ILoggingService; BuildEventArgTransportSink sink = new BuildEventArgTransportSink(SendLoggingPacket); _shutdownException = null; try { // If there are no node loggers to initialize dont do anything if (configuration.LoggerDescriptions != null && configuration.LoggerDescriptions.Length > 0) { _loggingService.InitializeNodeLoggers(configuration.LoggerDescriptions, sink, configuration.NodeId); } } catch (Exception ex) { if (ExceptionHandling.IsCriticalException(ex)) { throw; } OnEngineException(ex); } _loggingService.OnLoggingThreadException += new LoggingExceptionDelegate(OnLoggingThreadException); string forwardPropertiesFromChild = Environment.GetEnvironmentVariable("MSBUILDFORWARDPROPERTIESFROMCHILD"); string[] propertyListToSerialize = null; // Get a list of properties which should be serialized if (!String.IsNullOrEmpty(forwardPropertiesFromChild)) { propertyListToSerialize = forwardPropertiesFromChild.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); } _loggingService.PropertiesToSerialize = propertyListToSerialize; _loggingService.RunningOnRemoteNode = true; string forwardAllProperties = Environment.GetEnvironmentVariable("MSBUILDFORWARDALLPROPERTIESFROMCHILD"); if (String.Equals(forwardAllProperties, "1", StringComparison.OrdinalIgnoreCase) || _buildParameters.LogInitialPropertiesAndItems) { _loggingService.SerializeAllProperties = true; } else { _loggingService.SerializeAllProperties = false; } // Now prep the buildRequestEngine for the build. _loggingContext = new NodeLoggingContext(_loggingService, configuration.NodeId, false /* inProcNode */); if (_shutdownException != null) { Exception exception; HandleShutdown(out exception); throw exception; } _buildRequestEngine.InitializeForBuild(_loggingContext); // Finally store off this configuration packet. _currentConfiguration = configuration; }
public IList <NodeInfo> CreateNodes(NodeConfiguration configuration, NodeAffinity affinity, int numberOfNodesToCreate) => throw new NotSupportedException("not used");
/// <summary> /// Factory for deserialization. /// </summary> internal static INodePacket FactoryForDeserialization(INodePacketTranslator translator) { NodeConfiguration configuration = new NodeConfiguration(); configuration.Translate(translator); return configuration; }