/// <summary> /// Factory for deserialization. /// </summary> internal static INodePacket FactoryForDeserialization(ITranslator translator) { TaskHostConfiguration configuration = new TaskHostConfiguration(); configuration.Translate(translator); return(configuration); }
/// <summary> /// Instantiates a new MSBuild or MSBuildTaskHost process acting as a child node. /// </summary> internal bool CreateNode(HandshakeOptions hostContext, INodePacketFactory factory, INodePacketHandler handler, TaskHostConfiguration configuration) { ErrorUtilities.VerifyThrowArgumentNull(factory, "factory"); ErrorUtilities.VerifyThrow(!_nodeIdToPacketFactory.ContainsKey((int)hostContext), "We should not already have a factory for this context! Did we forget to call DisconnectFromHost somewhere?"); if (AvailableNodes == 0) { 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 2, to indicate that we // want to start up an MSBuild task host node. string commandLineArgs = $" /nologo /nodemode:2 /nodereuse:{ComponentHost.BuildParameters.EnableNodeReuse} "; string msbuildLocation = GetMSBuildLocationFromHostContext(hostContext); // we couldn't even figure out the location we're trying to launch ... just go ahead and fail. if (msbuildLocation == null) { return(false); } CommunicationsUtilities.Trace("For a host context of {0}, spawning executable from {1}.", hostContext.ToString(), msbuildLocation ?? "MSBuild.exe"); // Make it here. NodeContext context = GetNode ( msbuildLocation, commandLineArgs, (int)hostContext, this, CommunicationsUtilities.GetHostHandshake(hostContext), CommunicationsUtilities.GetClientHandshake(hostContext), NodeContextTerminated ); if (null != context) { _nodeContexts[hostContext] = context; // Start the asynchronous read. context.BeginAsyncPacketRead(); _activeNodes.Add((int)hostContext); _noNodesActiveEvent.Reset(); return(true); } return(false); }
/// <summary> /// Make sure a node in the requested context exists. /// </summary> internal bool AcquireAndSetUpHost(HandshakeOptions hostContext, INodePacketFactory factory, INodePacketHandler handler, TaskHostConfiguration configuration) { NodeContext context = null; bool nodeCreationSucceeded = false; if (!(_nodeContexts.TryGetValue(hostContext, out context))) { nodeCreationSucceeded = CreateNode(hostContext, factory, handler, configuration); } else { // node already exists, so "creation" automatically succeeded nodeCreationSucceeded = true; } if (nodeCreationSucceeded) { context = _nodeContexts[hostContext]; _nodeIdToPacketFactory[(int)hostContext] = factory; _nodeIdToPacketHandler[(int)hostContext] = handler; // Configure the node. context.SendData(configuration); return(true); } return(false); }
/// <summary> /// Executes the task. /// </summary> public bool Execute() { // log that we are about to spawn the task host string runtime = _taskHostParameters[XMakeAttributes.runtime]; string architecture = _taskHostParameters[XMakeAttributes.architecture]; _taskLoggingContext.LogComment(MessageImportance.Low, "ExecutingTaskInTaskHost", _taskType.Type.Name, _taskType.Assembly.AssemblyLocation, runtime, architecture); // set up the node lock (_taskHostLock) { _taskHostProvider = (NodeProviderOutOfProcTaskHost)_buildComponentHost.GetComponent(BuildComponentType.OutOfProcTaskHostNodeProvider); ErrorUtilities.VerifyThrowInternalNull(_taskHostProvider, "taskHostProvider"); } TaskHostConfiguration hostConfiguration = new TaskHostConfiguration ( _buildComponentHost.BuildParameters.NodeId, NativeMethodsShared.GetCurrentDirectory(), CommunicationsUtilities.GetEnvironmentVariables(), _buildComponentHost.BuildParameters.Culture, _buildComponentHost.BuildParameters.UICulture, #if FEATURE_APPDOMAIN _appDomainSetup, #endif BuildEngine.LineNumberOfTaskNode, BuildEngine.ColumnNumberOfTaskNode, BuildEngine.ProjectFileOfTaskNode, BuildEngine.ContinueOnError, _taskType.Type.FullName, AssemblyUtilities.GetAssemblyLocation(_taskType.Type.GetTypeInfo().Assembly), _setParameters, new Dictionary <string, string>(_buildComponentHost.BuildParameters.GlobalProperties) ); try { lock (_taskHostLock) { _requiredContext = CommunicationsUtilities.GetHandshakeOptions(taskHost: true, taskHostParameters: _taskHostParameters); _connectedToTaskHost = _taskHostProvider.AcquireAndSetUpHost(_requiredContext, this, this, hostConfiguration); } if (_connectedToTaskHost) { try { bool taskFinished = false; while (!taskFinished) { _packetReceivedEvent.WaitOne(); INodePacket packet = null; // Handle the packet that's coming in while (_receivedPackets.TryDequeue(out packet)) { if (packet != null) { HandlePacket(packet, out taskFinished); } } } } finally { lock (_taskHostLock) { _taskHostProvider.DisconnectFromHost(_requiredContext); _connectedToTaskHost = false; } } } else { LogErrorUnableToCreateTaskHost(_requiredContext, runtime, architecture, null); } } catch (BuildAbortedException) { LogErrorUnableToCreateTaskHost(_requiredContext, runtime, architecture, null); } catch (NodeFailedToLaunchException e) { LogErrorUnableToCreateTaskHost(_requiredContext, runtime, architecture, e); } return(_taskExecutionSucceeded); }