Beispiel #1
0
        /// <summary>
        /// Perform necessary actions to shut down the node.
        /// </summary>
        private NodeEngineShutdownReason HandleShutdown(out Exception exception)
        {
            if (_debugCommunications)
            {
                using (StreamWriter writer = File.CreateText(String.Format(CultureInfo.CurrentCulture, Path.Combine(Path.GetTempPath(), @"MSBuild_NodeShutdown_{0}.txt"), Process.GetCurrentProcess().Id)))
                {
                    writer.WriteLine("Node shutting down with reason {0} and exception: {1}", _shutdownReason, _shutdownException);
                }
            }

            // Clean up the engine
            if (null != _buildRequestEngine && _buildRequestEngine.Status != BuildRequestEngineStatus.Uninitialized)
            {
                _buildRequestEngine.CleanupForBuild();

                if (_shutdownReason == NodeEngineShutdownReason.BuildCompleteReuse)
                {
                    ((IBuildComponent)_buildRequestEngine).ShutdownComponent();
                }
            }

            // Dispose of any build registered objects
            IRegisteredTaskObjectCache objectCache = (IRegisteredTaskObjectCache)(_componentFactories.GetComponent(BuildComponentType.RegisteredTaskObjectCache));

            objectCache.DisposeCacheObjects(RegisteredTaskObjectLifetime.Build);

            if (_shutdownReason != NodeEngineShutdownReason.BuildCompleteReuse)
            {
                // Dispose of any node registered objects.
                ((IBuildComponent)objectCache).ShutdownComponent();
            }

            // Shutdown any Out Of Proc Nodes Created
            _taskHostNodeManager.ShutdownConnectedNodes(_shutdownReason == NodeEngineShutdownReason.BuildCompleteReuse);

#if FEATURE_ENVIRONMENT_SYSTEMDIRECTORY
            // Restore the original current directory.
            NativeMethodsShared.SetCurrentDirectory(Environment.SystemDirectory);
#endif

            // Restore the original environment.
            // If the node was never configured, this will be null.
            if (_savedEnvironment != null)
            {
                foreach (KeyValuePair <string, string> entry in CommunicationsUtilities.GetEnvironmentVariables())
                {
                    if (!_savedEnvironment.ContainsKey(entry.Key))
                    {
                        Environment.SetEnvironmentVariable(entry.Key, null);
                    }
                }

                foreach (KeyValuePair <string, string> entry in _savedEnvironment)
                {
                    Environment.SetEnvironmentVariable(entry.Key, entry.Value);
                }
            }

            try
            {
                // Shut down logging, which will cause all queued logging messages to be sent.
                if (null != _loggingContext && null != _loggingService)
                {
                    _loggingContext.LogBuildFinished(true);
                    ((IBuildComponent)_loggingService).ShutdownComponent();
                }
            }
            finally
            {
                // Shut down logging, which will cause all queued logging messages to be sent.
                if (null != _loggingContext && null != _loggingService)
                {
                    _loggingContext.LoggingService.OnLoggingThreadException -= new LoggingExceptionDelegate(OnLoggingThreadException);
                    _loggingContext = null;
                }

                exception = _shutdownException;

                if (_nodeEndpoint.LinkStatus == LinkStatus.Active)
                {
                    // Notify the BuildManager that we are done.
                    _nodeEndpoint.SendData(new NodeShutdown(_shutdownReason == NodeEngineShutdownReason.Error ? NodeShutdownReason.Error : NodeShutdownReason.Requested, exception));

                    // Flush all packets to the pipe and close it down.  This blocks until the shutdown is complete.
                    _nodeEndpoint.OnLinkStatusChanged -= new LinkStatusChangedDelegate(OnLinkStatusChanged);
                }

                _nodeEndpoint.Disconnect();
                CleanupCaches();
            }

            return(_shutdownReason);
        }
Beispiel #2
0
        /// <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)
            {
#if FEATURE_ENVIRONMENT_SYSTEMDIRECTORY
                // Somehow the startup directory vanished. This can happen if build was started from a USB Key and it was removed.
                NativeMethodsShared.SetCurrentDirectory(Environment.SystemDirectory);
#endif
            }

            // 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.
#if FEATURE_CULTUREINFO_SETTERS
            CultureInfo.CurrentCulture   = _buildParameters.Culture;
            CultureInfo.CurrentUICulture = _buildParameters.UICulture;
#else
            Thread.CurrentThread.CurrentCulture   = _buildParameters.Culture;
            Thread.CurrentThread.CurrentUICulture = _buildParameters.UICulture;
#endif

            // Get the node ID.
            _buildParameters.NodeId      = configuration.NodeId;
            _buildParameters.IsOutOfProc = true;

#if FEATURE_APPDOMAIN
            // And the AppDomainSetup
            _buildParameters.AppDomainSetup = configuration.AppDomainSetup;
#endif

            // 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;
        }
Beispiel #3
0
 public bool DirectoryExists(string path)
 {
     return(NativeMethodsShared.DirectoryExists(path));
 }
Beispiel #4
0
 public bool FileExists(string path)
 {
     return(NativeMethodsShared.FileExists(path));
 }
        private void SimpleSymlinkInputCheck(DateTime symlinkWriteTime, DateTime targetWriteTime,
                                             DateTime outputWriteTime, bool expectedOutOfDate)
        {
            var inputs = new List <string>();

            var outputs = new List <string>();

            string inputTarget  = "NONEXISTENT_FILE";
            string inputSymlink = "NONEXISTENT_FILE";
            string outputTarget = "NONEXISTENT_FILE";

            try
            {
                inputTarget = FileUtilities.GetTemporaryFile();
                _testOutputHelper.WriteLine($"Created input file {inputTarget}");
                File.SetLastWriteTime(inputTarget, targetWriteTime);

                inputSymlink = FileUtilities.GetTemporaryFile(null, ".linkin", createFile: false);

                if (!CreateSymbolicLink(inputSymlink, inputTarget, 0))
                {
                    Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                }

                // File.SetLastWriteTime on the symlink sets the target write time,
                // so set the symlink's write time the hard way
                using (SafeFileHandle handle =
                           NativeMethodsShared.CreateFile(
                               inputSymlink, NativeMethodsShared.GENERIC_READ | 0x100 /* FILE_WRITE_ATTRIBUTES */,
                               NativeMethodsShared.FILE_SHARE_READ, IntPtr.Zero, NativeMethodsShared.OPEN_EXISTING,
                               NativeMethodsShared.FILE_ATTRIBUTE_NORMAL | NativeMethodsShared.FILE_FLAG_OPEN_REPARSE_POINT,
                               IntPtr.Zero))
                {
                    if (handle.IsInvalid)
                    {
                        Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                    }

                    long symlinkWriteTimeTicks = symlinkWriteTime.ToFileTimeUtc();

                    if (SetFileTime(handle, ref symlinkWriteTimeTicks, ref symlinkWriteTimeTicks,
                                    ref symlinkWriteTimeTicks) != true)
                    {
                        Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
                    }
                }

                _testOutputHelper.WriteLine($"Created input link {inputSymlink}");

                outputTarget = FileUtilities.GetTemporaryFile();
                _testOutputHelper.WriteLine($"Created output file {outputTarget}");
                File.SetLastWriteTime(outputTarget, outputWriteTime);

                inputs.Add(inputSymlink);
                outputs.Add(outputTarget);


                DependencyAnalysisLogDetail detail;
                Assert.Equal(expectedOutOfDate,
                             TargetUpToDateChecker.IsAnyOutOfDate(out detail, Directory.GetCurrentDirectory(), inputs, outputs));
            }
            finally
            {
                if (File.Exists(inputTarget))
                {
                    File.Delete(inputTarget);
                }
                if (File.Exists(inputSymlink))
                {
                    File.Delete(inputSymlink);
                }
                if (File.Exists(outputTarget))
                {
                    File.Delete(outputTarget);
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Reads the settings for a specified tools version
        /// </summary>
        private Toolset ReadToolset
        (
            ToolsetPropertyDefinition toolsVersion,
            PropertyDictionary <ProjectPropertyInstance> globalProperties,
            PropertyDictionary <ProjectPropertyInstance> initialProperties,
            bool accumulateProperties
        )
        {
            // Initial properties is the set of properties we're going to use to expand property expressions like $(foo)
            // in the values we read out of the registry or config file. We'll add to it as we pick up properties (including binpath)
            // from the registry or config file, so that properties there can be referenced in values below them.
            // After processing all the properties, we don't need initialProperties anymore.
            string toolsPath = null;
            string binPath   = null;
            PropertyDictionary <ProjectPropertyInstance> properties = new PropertyDictionary <ProjectPropertyInstance>();

            IEnumerable <ToolsetPropertyDefinition> rawProperties = GetPropertyDefinitions(toolsVersion.Name);

            Expander <ProjectPropertyInstance, ProjectItemInstance> expander = new Expander <ProjectPropertyInstance, ProjectItemInstance>(initialProperties);

            foreach (ToolsetPropertyDefinition property in rawProperties)
            {
                EvaluateAndSetProperty(property, properties, globalProperties, initialProperties, accumulateProperties, ref toolsPath, ref binPath, ref expander);
            }

            Dictionary <string, SubToolset> subToolsets        = new Dictionary <string, SubToolset>(StringComparer.OrdinalIgnoreCase);
            IEnumerable <string>            subToolsetVersions = GetSubToolsetVersions(toolsVersion.Name);

            foreach (string subToolsetVersion in subToolsetVersions)
            {
                string subToolsetToolsPath = null;
                string subToolsetBinPath   = null;
                IEnumerable <ToolsetPropertyDefinition>      rawSubToolsetProperties = GetSubToolsetPropertyDefinitions(toolsVersion.Name, subToolsetVersion);
                PropertyDictionary <ProjectPropertyInstance> subToolsetProperties    = new PropertyDictionary <ProjectPropertyInstance>();

                // If we have a sub-toolset, any values defined here will override the toolset properties.
                foreach (ToolsetPropertyDefinition property in rawSubToolsetProperties)
                {
                    EvaluateAndSetProperty(property, subToolsetProperties, globalProperties, initialProperties, false /* do not ever accumulate sub-toolset properties */, ref subToolsetToolsPath, ref subToolsetBinPath, ref expander);
                }

                if (subToolsetToolsPath != null || subToolsetBinPath != null)
                {
                    InvalidToolsetDefinitionException.Throw("MSBuildToolsPathNotSupportedInSubToolsets", toolsVersion.Name, toolsVersion.Source.LocationString, subToolsetVersion);
                }

                subToolsets[subToolsetVersion] = new SubToolset(subToolsetVersion, subToolsetProperties);
            }

            // All tools versions must specify a value for MSBuildToolsPath (or MSBuildBinPath)
            if (String.IsNullOrEmpty(toolsPath) && String.IsNullOrEmpty(binPath))
            {
                return(null);
            }

            // If both MSBuildBinPath and MSBuildToolsPath are present, they must be the same
            if (toolsPath != null && binPath != null && !toolsPath.Equals(binPath, StringComparison.OrdinalIgnoreCase))
            {
                InvalidToolsetDefinitionException.Throw("ConflictingValuesOfMSBuildToolsPath", toolsVersion.Name, toolsVersion.Source.LocationString);
            }

            AppendStandardProperties(properties, globalProperties, toolsVersion.Name, null, toolsPath);
            Toolset toolset = null;

            try
            {
                var importSearchPathsTable = GetProjectImportSearchPathsTable(toolsVersion.Name, NativeMethodsShared.GetOSNameForExtensionsPath());
                toolset = new Toolset(toolsVersion.Name, toolsPath == null ? binPath : toolsPath, properties, _environmentProperties, globalProperties, subToolsets, MSBuildOverrideTasksPath, DefaultOverrideToolsVersion, importSearchPathsTable);
            }
            catch (ArgumentException e)
            {
                InvalidToolsetDefinitionException.Throw("ErrorCreatingToolset", toolsVersion.Name, e.Message);
            }

            return(toolset);
        }
Beispiel #7
0
        /// <summary>
        /// Perform necessary actions to shut down the node.
        /// </summary>
        private NodeEngineShutdownReason HandleShutdown(out Exception exception)
        {
            CommunicationsUtilities.Trace("Shutting down with reason: {0}, and exception: {1}.", _shutdownReason, _shutdownException);

            // Clean up the engine
            if (null != _buildRequestEngine && _buildRequestEngine.Status != BuildRequestEngineStatus.Uninitialized)
            {
                _buildRequestEngine.CleanupForBuild();

                if (_shutdownReason == NodeEngineShutdownReason.BuildCompleteReuse)
                {
                    ((IBuildComponent)_buildRequestEngine).ShutdownComponent();
                }
            }

            // Signal the SDK resolver service to shutdown
            ((IBuildComponent)_sdkResolverService).ShutdownComponent();

            // Dispose of any build registered objects
            IRegisteredTaskObjectCache objectCache = (IRegisteredTaskObjectCache)(_componentFactories.GetComponent(BuildComponentType.RegisteredTaskObjectCache));
            objectCache.DisposeCacheObjects(RegisteredTaskObjectLifetime.Build);

            if (_shutdownReason != NodeEngineShutdownReason.BuildCompleteReuse)
            {
                // Dispose of any node registered objects.
                ((IBuildComponent)objectCache).ShutdownComponent();
            }

            // Shutdown any Out Of Proc Nodes Created
            _taskHostNodeManager.ShutdownConnectedNodes(_shutdownReason == NodeEngineShutdownReason.BuildCompleteReuse);

            // On Windows, a process holds a handle to the current directory,
            // so reset it away from a user-requested folder that may get deleted.
            NativeMethodsShared.SetCurrentDirectory(BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory);

            // Restore the original environment.
            // If the node was never configured, this will be null.
            if (_savedEnvironment != null)
            {
                foreach (KeyValuePair<string, string> entry in CommunicationsUtilities.GetEnvironmentVariables())
                {
                    if (!_savedEnvironment.ContainsKey(entry.Key))
                    {
                        Environment.SetEnvironmentVariable(entry.Key, null);
                    }
                }

                foreach (KeyValuePair<string, string> entry in _savedEnvironment)
                {
                    Environment.SetEnvironmentVariable(entry.Key, entry.Value);
                }
            }

            try
            {
                // Shut down logging, which will cause all queued logging messages to be sent.
                if (null != _loggingContext && null != _loggingService)
                {
                    _loggingContext.LogBuildFinished(true);
                    ((IBuildComponent)_loggingService).ShutdownComponent();
                }
            }
            finally
            {
                // Shut down logging, which will cause all queued logging messages to be sent.
                if (null != _loggingContext && null != _loggingService)
                {
                    _loggingContext.LoggingService.OnLoggingThreadException -= OnLoggingThreadException;
                    _loggingContext = null;
                }

                exception = _shutdownException;

                if (_nodeEndpoint.LinkStatus == LinkStatus.Active)
                {
                    // Notify the BuildManager that we are done.
                    _nodeEndpoint.SendData(new NodeShutdown(_shutdownReason == NodeEngineShutdownReason.Error ? NodeShutdownReason.Error : NodeShutdownReason.Requested, exception));

                    // Flush all packets to the pipe and close it down.  This blocks until the shutdown is complete.
                    _nodeEndpoint.OnLinkStatusChanged -= OnLinkStatusChanged;
                }

                _nodeEndpoint.Disconnect();
                CleanupCaches();
            }

            CommunicationsUtilities.Trace("Shut down complete.");

            return _shutdownReason;
        }
Beispiel #8
0
        /// <summary>
        /// Creates a new MSBuild process
        /// </summary>
        private int LaunchNode(string msbuildLocation, string commandLineArgs)
        {
            // Should always have been set already.
            ErrorUtilities.VerifyThrowInternalLength(msbuildLocation, "msbuildLocation");

            if (!File.Exists(msbuildLocation))
            {
                throw new BuildAbortedException(ResourceUtilities.FormatResourceString("CouldNotFindMSBuildExe", msbuildLocation));
            }

            // Repeat the executable name as the first token of the command line because the command line
            // parser logic expects it and will otherwise skip the first argument
            commandLineArgs = msbuildLocation + " " + commandLineArgs;

            BackendNativeMethods.STARTUP_INFO startInfo = new BackendNativeMethods.STARTUP_INFO();
            startInfo.cb = Marshal.SizeOf <BackendNativeMethods.STARTUP_INFO>();

            // Null out the process handles so that the parent process does not wait for the child process
            // to exit before it can exit.
            uint creationFlags = 0;

            if (Traits.Instance.EscapeHatches.EnsureStdOutForChildNodesIsPrimaryStdout)
            {
                creationFlags = BackendNativeMethods.NORMALPRIORITYCLASS;
            }

            if (String.IsNullOrEmpty(Environment.GetEnvironmentVariable("MSBUILDNODEWINDOW")))
            {
                if (!Traits.Instance.EscapeHatches.EnsureStdOutForChildNodesIsPrimaryStdout)
                {
                    startInfo.hStdError  = BackendNativeMethods.InvalidHandle;
                    startInfo.hStdInput  = BackendNativeMethods.InvalidHandle;
                    startInfo.hStdOutput = BackendNativeMethods.InvalidHandle;
                    startInfo.dwFlags    = BackendNativeMethods.STARTFUSESTDHANDLES;
                    creationFlags        = creationFlags | BackendNativeMethods.CREATENOWINDOW;
                }
            }
            else
            {
                creationFlags = creationFlags | BackendNativeMethods.CREATE_NEW_CONSOLE;
            }

            BackendNativeMethods.SECURITY_ATTRIBUTES processSecurityAttributes = new BackendNativeMethods.SECURITY_ATTRIBUTES();
            BackendNativeMethods.SECURITY_ATTRIBUTES threadSecurityAttributes  = new BackendNativeMethods.SECURITY_ATTRIBUTES();
            processSecurityAttributes.nLength = Marshal.SizeOf <BackendNativeMethods.SECURITY_ATTRIBUTES>();
            threadSecurityAttributes.nLength  = Marshal.SizeOf <BackendNativeMethods.SECURITY_ATTRIBUTES>();

            CommunicationsUtilities.Trace("Launching node from {0}", msbuildLocation);

            string exeName = msbuildLocation;

#if RUNTIME_TYPE_NETCORE
            // Run the child process with the same host as the currently-running process.
            exeName         = GetCurrentHost();
            commandLineArgs = "\"" + msbuildLocation + "\" " + commandLineArgs;
#endif

            if (!NativeMethodsShared.IsWindows)
            {
                ProcessStartInfo processStartInfo = new ProcessStartInfo();
                processStartInfo.FileName  = exeName;
                processStartInfo.Arguments = commandLineArgs;
                if (!Traits.Instance.EscapeHatches.EnsureStdOutForChildNodesIsPrimaryStdout)
                {
                    processStartInfo.CreateNoWindow = (creationFlags | BackendNativeMethods.CREATENOWINDOW) == BackendNativeMethods.CREATENOWINDOW;
                }
                processStartInfo.UseShellExecute = false;

                Process process;
                try
                {
                    process = Process.Start(processStartInfo);
                }
                catch (Exception ex)
                {
                    CommunicationsUtilities.Trace
                    (
                        "Failed to launch node from {0}. CommandLine: {1}" + Environment.NewLine + "{2}",
                        msbuildLocation,
                        commandLineArgs,
                        ex.ToString()
                    );

                    throw new NodeFailedToLaunchException(ex);
                }

                CommunicationsUtilities.Trace("Successfully launched msbuild.exe node with PID {0}", process.Id);
                return(process.Id);
            }
            else
            {
#if RUNTIME_TYPE_NETCORE
                if (NativeMethodsShared.IsWindows)
                {
                    // Repeat the executable name in the args to suit CreateProcess
                    commandLineArgs = "\"" + exeName + "\" " + commandLineArgs;
                }
#endif

                BackendNativeMethods.PROCESS_INFORMATION processInfo = new BackendNativeMethods.PROCESS_INFORMATION();

                bool result = BackendNativeMethods.CreateProcess
                              (
                    exeName,
                    commandLineArgs,
                    ref processSecurityAttributes,
                    ref threadSecurityAttributes,
#if FEATURE_NAMED_PIPES_FULL_DUPLEX
                    false,
#else
                    true,     // Inherit handles for the anonymous pipes for IPC
#endif
                    creationFlags,
                    BackendNativeMethods.NullPtr,
                    null,
                    ref startInfo,
                    out processInfo
                              );

                if (!result)
                {
                    // Creating an instance of this exception calls GetLastWin32Error and also converts it to a user-friendly string.
                    System.ComponentModel.Win32Exception e = new System.ComponentModel.Win32Exception();

                    CommunicationsUtilities.Trace
                    (
                        "Failed to launch node from {0}. System32 Error code {1}. Description {2}. CommandLine: {2}",
                        msbuildLocation,
                        e.NativeErrorCode.ToString(CultureInfo.InvariantCulture),
                        e.Message,
                        commandLineArgs
                    );

                    throw new NodeFailedToLaunchException(e.NativeErrorCode.ToString(CultureInfo.InvariantCulture), e.Message);
                }

                int childProcessId = processInfo.dwProcessId;

                if (processInfo.hProcess != IntPtr.Zero && processInfo.hProcess != NativeMethods.InvalidHandle)
                {
                    NativeMethodsShared.CloseHandle(processInfo.hProcess);
                }

                if (processInfo.hThread != IntPtr.Zero && processInfo.hThread != NativeMethods.InvalidHandle)
                {
                    NativeMethodsShared.CloseHandle(processInfo.hThread);
                }

                CommunicationsUtilities.Trace("Successfully launched msbuild.exe node with PID {0}", childProcessId);
                return(childProcessId);
            }
        }
Beispiel #9
0
        /// <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.GetTaskHostContext(_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);
        }