Пример #1
0
        /// <summary>
        /// Read the provided binary log file and raise corresponding events for each BuildEventArgs
        /// </summary>
        /// <param name="sourceFilePath">The full file path of the binary log file</param>
        /// <param name="cancellationToken">A <see cref="CancellationToken"/> indicating the replay should stop as soon as possible.</param>
        public void Replay(string sourceFilePath, CancellationToken cancellationToken)
        {
            using (var stream = new FileStream(sourceFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                var gzipStream   = new GZipStream(stream, CompressionMode.Decompress, leaveOpen: true);
                var binaryReader = new BinaryReader(gzipStream);

                int fileFormatVersion = binaryReader.ReadInt32();

                // the log file is written using a newer version of file format
                // that we don't know how to read
                if (fileFormatVersion > BinaryLogger.FileFormatVersion)
                {
                    var text = ResourceUtilities.FormatResourceString("UnsupportedLogFileFormat", fileFormatVersion, BinaryLogger.FileFormatVersion);
                    throw new NotSupportedException(text);
                }

                var reader = new BuildEventArgsReader(binaryReader, fileFormatVersion);
                while (true)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return;
                    }

                    BuildEventArgs instance = null;

                    instance = reader.Read();
                    if (instance == null)
                    {
                        break;
                    }

                    Dispatch(instance);
                }
            }
        }
        /// <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));
        }
        public void VerifyInvalidProjectSchema
        (
        )
        {
            string[] msbuildTempXsdFilenames = new string[] {};
            try
            {
                // Create schema files in the temp folder
                msbuildTempXsdFilenames = PrepareSchemaFiles();

                string projectContents = @"
                    <Project xmlns=`msbuildnamespace`>
                        <MyInvalidTag/>
                        <Target Name=`Build` />
                    </Project>
                    ";

                Engine buildEngine = new Engine(@"c:\");
                ProjectSchemaValidationHandler validator = new ProjectSchemaValidationHandler(null, buildEngine.LoggingServices, @"c:\");

                try
                {
                    validator.VerifyProjectSchema(ObjectModelHelpers.CleanupFileContents(projectContents),
                                                  msbuildTempXsdFilenames[0]);
                }
                catch (InvalidProjectFileException e)
                {
                    Assertion.AssertEquals(e.BaseMessage, ResourceUtilities.FormatResourceString("ProjectSchemaErrorHalt"));

                    throw;
                }
            }
            finally
            {
                CleanupSchemaFiles(msbuildTempXsdFilenames);
            }
        }
Пример #4
0
        public void Initialize(IEventSource eventSource)
        {
            ErrorUtilities.VerifyThrowArgumentNull(eventSource, nameof(eventSource));
            ParseFileLoggerParameters();
            string fileName = logFile;

            try
            {
                // Create a new file logger and pass it some parameters to make the build log very detailed
                nodeFileLogger = new FileLogger();
                string extension = Path.GetExtension(logFile);
                // If there is no extension add a default of .log to it
                if (String.IsNullOrEmpty(extension))
                {
                    logFile  += ".log";
                    extension = ".log";
                }
                // Log 0-based node id's, where 0 is the parent. This is a little unnatural for the reader,
                // but avoids confusion by being consistent with the Engine and any error messages it may produce.
                fileName = logFile.Replace(extension, nodeId + extension);
                nodeFileLogger.Verbosity  = LoggerVerbosity.Detailed;
                nodeFileLogger.Parameters = "ShowEventId;ShowCommandLine;logfile=" + fileName + ";" + parameters;
            }
            catch (ArgumentException e) // Catching Exception, but rethrowing unless it's a well-known exception.
            {
                nodeFileLogger?.Shutdown();

                string errorCode;
                string helpKeyword;
                string message = ResourceUtilities.FormatResourceString(out errorCode, out helpKeyword, "InvalidFileLoggerFile", fileName, e.Message);
                throw new LoggerException(message, e, errorCode, helpKeyword);
            }

            // Say we are operating on 2 processors so we can get the multiproc output
            nodeFileLogger.Initialize(eventSource, 2);
        }
Пример #5
0
        /// <summary>
        /// Gets the working directory to use for the process. Should return null if ToolTask should use the
        /// current directory.
        /// May throw an IOException if the directory to be used is somehow invalid.
        /// </summary>
        /// <returns>working directory</returns>
        protected override string GetWorkingDirectory()
        {
            // If the working directory is UNC, we're going to use "pushd" in the batch file to set it.
            // If it's invalid, pushd won't fail: it will just go ahead and use the system folder.
            // So verify it's valid here.
            if (!Directory.Exists(_workingDirectory))
            {
                throw new DirectoryNotFoundException(ResourceUtilities.FormatResourceString("Exec.InvalidWorkingDirectory", _workingDirectory));
            }

            if (workingDirectoryIsUNC)
            {
                // if the working directory for the exec command is UNC, set the process working directory to the system path
                // so that it doesn't display this silly error message:
                //      '\\<server>\<share>'
                //      CMD.EXE was started with the above path as the current directory.
                //      UNC paths are not supported.  Defaulting to Windows directory.
                return(ToolLocationHelper.PathToSystem);
            }
            else
            {
                return(_workingDirectory);
            }
        }
        /// <summary>
        /// Apply the verbosity value
        /// </summary>
        private bool ApplyVerbosityParameter(string parameterValue)
        {
            switch (parameterValue.ToUpperInvariant())
            {
            case "Q":
            case "QUIET":
                Verbosity = LoggerVerbosity.Quiet;
                return(true);

            case "M":
            case "MINIMAL":
                Verbosity = LoggerVerbosity.Minimal;
                return(true);

            case "N":
            case "NORMAL":
                Verbosity = LoggerVerbosity.Normal;
                return(true);

            case "D":
            case "DETAILED":
                Verbosity = LoggerVerbosity.Detailed;
                return(true);

            case "DIAG":
            case "DIAGNOSTIC":
                Verbosity = LoggerVerbosity.Diagnostic;
                return(true);

            default:
                string errorCode;
                string helpKeyword;
                string message = ResourceUtilities.FormatResourceString(out errorCode, out helpKeyword, "InvalidVerbosity", parameterValue);
                throw new LoggerException(message, null, errorCode, helpKeyword);
            }
        }
Пример #7
0
        private bool ParseAsContentOrFile(string contentOrFile, string desiredRule)
        {
            // On Windows:
            // - xml string will be an invalid file path, so, Path.GetFullPath will
            //   return null
            // - xml string cannot be a rooted path ("C:\\<abc />")
            //
            // On Unix:
            // - xml string is a valid path, this is not a definite check as Path.GetFullPath
            //   will return !null in most cases
            // - xml string cannot be a rooted path ("/foo/<abc />")

            bool   isRootedPath  = false;
            string maybeFullPath = null;

            try
            {
                isRootedPath = Path.IsPathRooted(contentOrFile);
                if (!isRootedPath)
                {
                    maybeFullPath = Path.GetFullPath(contentOrFile);
                }
            }
            catch (Exception e)
            {
                if (ExceptionHandling.IsCriticalException(e))
                {
                    throw;
                }

                // We will get an exception if the contents are not a path (for instance, they are actual XML.)
            }

            if (isRootedPath)
            {
                // valid *absolute* file path

                if (!File.Exists(contentOrFile))
                {
                    throw new ArgumentException(ResourceUtilities.FormatResourceString("Xaml.RuleFileNotFound", contentOrFile));
                }

                return(ParseXamlDocument(new StreamReader(contentOrFile), desiredRule));
            }

            // On Windows, xml content string is not a valid path, so, maybeFullPath == null
            // On Unix, xml content string would be a valid path, so, maybeFullPath != null
            if (maybeFullPath == null)
            {
                // Unable to convert to a path, parse as XML
                return(ParseXamlDocument(new StringReader(contentOrFile), desiredRule));
            }

            if (File.Exists(maybeFullPath))
            {
                // file found, parse as a file
                return(ParseXamlDocument(new StreamReader(maybeFullPath), desiredRule));
            }

            // @maybeFullPath is either:
            //  - a non-existent fullpath
            //  - or xml content with the current dir prepended (like "/foo/bar/<abc .. />"),
            //    but not on Windows
            //
            // On Windows, this means that @contentOrFile is really a non-existant file name
            if (NativeMethodsShared.IsWindows)
            {
                throw new ArgumentException(ResourceUtilities.FormatResourceString("Xaml.RuleFileNotFound", maybeFullPath));
            }
            else // On !Windows, try parsing as XML
            {
                return(ParseXamlDocument(new StringReader(contentOrFile), desiredRule));
            }
        }
        /// <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)
                {
                    // Redirect the streams of worker nodes so that this MSBuild.exe's
                    // parent doesn't wait on idle worker nodes to close streams
                    // after the build is complete.
                    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)
                {
                    // Redirect the streams of worker nodes so that this MSBuild.exe's
                    // parent doesn't wait on idle worker nodes to close streams
                    // after the build is complete.
                    processStartInfo.RedirectStandardInput  = true;
                    processStartInfo.RedirectStandardOutput = true;
                    processStartInfo.RedirectStandardError  = true;
                    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);
            }
        }
Пример #9
0
        /// <summary>
        /// This function will start a node and send requests to it
        /// </summary>
        private void LaunchNodeAndPostBuildRequest()
        {
            int nodeIndex = 0;

            // Find out what node to launch
            lock (nodesToLaunch)
            {
                nodeIndex = nodesToLaunch.Dequeue();
            }

            // If the provider is shutting down - don't launch the node
            if (shuttingDown)
            {
                nodeData[nodeIndex].NodeState = NodeState.NotLaunched;
                return;
            }

            try
            {
                // Either launch node or connect to an already running node
                InitializeNode(nodeIndex);

                if (!nodeData[nodeIndex].CommunicationFailed)
                {
                    // Change the state of the node to launched
                    lock (nodeStateLock)
                    {
                        nodeData[nodeIndex].NodeState = NodeState.Launched;
                    }

                    // Send all the requests to the node. Note that the requests may end up in
                    // mixed order with the request currently being posted.
                    LinkedListNode <BuildRequest> current = nodeData[nodeIndex].TargetList.First;
                    BuildRequest[] buildRequests          = new BuildRequest[nodeData[nodeIndex].TargetList.Count];
                    int            i = 0;
                    while (current != null)
                    {
                        buildRequests[i] = current.Value;
                        i++;

                        current = current.Next;
                    }
                    LocalCallDescriptorForPostBuildRequests callDescriptor =
                        new LocalCallDescriptorForPostBuildRequests(buildRequests);
                    nodeData[nodeIndex].NodeCommandQueue.Enqueue(callDescriptor);

                    nodeData[nodeIndex].TargetList = null;
                }
                else
                {
                    // Allow the engine to decide how to proceed since the node failed to launch
                    string message = ResourceUtilities.FormatResourceString("NodeProviderFailure");
                    ReportNodeCommunicationFailure(nodeIndex, new Exception(message), false);
                }
            }
            catch (Exception e)
            {
                // Allow the engine to deal with the exception
                ReportNodeCommunicationFailure(nodeIndex, e, false);
            }
        }
Пример #10
0
        /// <summary>
        /// Apply a logger parameter.
        /// parameterValue may be null, if there is no parameter value.
        /// </summary>
        internal virtual bool ApplyParameter(string parameterName, string parameterValue)
        {
            ErrorUtilities.VerifyThrowArgumentNull(parameterName, "parameterName");

            switch (parameterName.ToUpperInvariant())
            {
            case "PERFORMANCESUMMARY":
                showPerfSummary = true;
                return(true);

            case "NOSUMMARY":
                showSummary = false;
                return(true);

            case "SUMMARY":
                showSummary = true;
                return(true);

            case "NOITEMANDPROPERTYLIST":
                showItemAndPropertyList = false;
                return(true);

            case "WARNINGSONLY":
                showOnlyWarnings = true;
                return(true);

            case "ERRORSONLY":
                showOnlyErrors = true;
                return(true);

            case "V":
            case "VERBOSITY":
            {
                switch (parameterValue.ToUpperInvariant())
                {
                case "Q":
                case "QUIET":
                    verbosity = LoggerVerbosity.Quiet;
                    return(true);

                case "M":
                case "MINIMAL":
                    verbosity = LoggerVerbosity.Minimal;
                    return(true);

                case "N":
                case "NORMAL":
                    verbosity = LoggerVerbosity.Normal;
                    return(true);

                case "D":
                case "DETAILED":
                    verbosity = LoggerVerbosity.Detailed;
                    return(true);

                case "DIAG":
                case "DIAGNOSTIC":
                    verbosity = LoggerVerbosity.Diagnostic;
                    return(true);

                default:
                    string errorCode;
                    string helpKeyword;
                    string message = ResourceUtilities.FormatResourceString(out errorCode, out helpKeyword, "InvalidVerbosity", parameterValue);
                    throw new LoggerException(message, null, errorCode, helpKeyword);
                }
            }
            }

            return(false);
        }
Пример #11
0
Файл: Node.cs Проект: 3F/IeXod
        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();
            }
        }
Пример #12
0
        /// <summary>
        /// Finds or creates a child process which can act as a node.
        /// </summary>
        /// <returns>The pipe stream representing the node.</returns>
        protected NodeContext GetNode(string msbuildLocation, string commandLineArgs, int nodeId, INodePacketFactory factory, long hostHandshake, long clientHandshake, NodeContextTerminateDelegate terminateNode)
        {
            if (String.IsNullOrEmpty(msbuildLocation))
            {
                msbuildLocation = _componentHost.BuildParameters.NodeExeLocation;
            }

            if (String.IsNullOrEmpty(msbuildLocation))
            {
                string msbuildExeName = Environment.GetEnvironmentVariable("MSBUILD_EXE_NAME");

                if (!String.IsNullOrEmpty(msbuildExeName))
                {
                    // we assume that MSBUILD_EXE_NAME is, in fact, just the name.
                    msbuildLocation = Path.Combine(msbuildExeName, ".exe");
                }
            }

            if (String.IsNullOrEmpty(msbuildLocation))
            {
                msbuildLocation = "MSBuild.exe";
            }

            string msbuildName = Path.GetFileNameWithoutExtension(msbuildLocation);

            List <Process> nodeProcesses = new List <Process>(Process.GetProcessesByName(msbuildName));

            // Trivial sort to try to prefer most recently used nodes
            nodeProcesses.Sort
            (
                delegate(Process left, Process right)
            {
                return(left.Id - right.Id);
            }

            );

            CommunicationsUtilities.Trace("Attempting to connect to each existing msbuild.exe process in turn to establish node {0}...", nodeId);
            foreach (Process nodeProcess in nodeProcesses)
            {
                if (nodeProcess.Id == Process.GetCurrentProcess().Id)
                {
                    continue;
                }

                // Get the full context of this inspection so that we can always skip this process when we have the same taskhost context
                string nodeLookupKey = GetProcessesToIgnoreKey(hostHandshake, clientHandshake, nodeProcess.Id);
                if (_processesToIgnore.Contains(nodeLookupKey))
                {
                    continue;
                }

                // We don't need to check this again
                _processesToIgnore.Add(nodeLookupKey);

                // Attempt to connect to each process in turn.
                NamedPipeClientStream nodeStream = TryConnectToProcess(nodeProcess.Id, 0 /* poll, don't wait for connections */, hostHandshake, clientHandshake);
                if (nodeStream != null)
                {
                    // Connection successful, use this node.
                    CommunicationsUtilities.Trace("Successfully connected to existed node {0} which is PID {1}", nodeId, nodeProcess.Id);
                    return(new NodeContext(nodeId, nodeProcess.Id, nodeStream, factory, terminateNode));
                }
            }

            // None of the processes we tried to connect to allowed a connection, so create a new one.
            // We try this in a loop because it is possible that there is another MSBuild multiproc
            // host process running somewhere which is also trying to create nodes right now.  It might
            // find our newly created node and connect to it before we get a chance.
            CommunicationsUtilities.Trace("Could not connect to existing process, now creating a process...");
            int retries = NodeCreationRetries;

            while (retries-- > 0)
            {
                // We will also check to see if .NET 3.5 is installed in the case where we need to launch a CLR2 OOP TaskHost.
                // Failure to detect this has been known to stall builds when Windows pops up a related dialog.
                // It's also a waste of time when we attempt several times to launch multiple MSBuildTaskHost.exe (CLR2 TaskHost)
                // nodes because we should never be able to connect in this case.
                string taskHostNameForClr2TaskHost = Path.GetFileNameWithoutExtension(NodeProviderOutOfProcTaskHost.TaskHostNameForClr2TaskHost);
                if (msbuildName.Equals(taskHostNameForClr2TaskHost, StringComparison.OrdinalIgnoreCase))
                {
                    if (FrameworkLocationHelper.GetPathToDotNetFrameworkV35(DotNetFrameworkArchitecture.Current) == null)
                    {
                        CommunicationsUtilities.Trace
                        (
                            "Failed to launch node from {0}. The required .NET Framework v3.5 is not installed or enabled. CommandLine: {1}",
                            msbuildLocation,
                            commandLineArgs
                        );

                        string nodeFailedToLaunchError = ResourceUtilities.FormatResourceString("TaskHostNodeFailedToLaunchErrorCodeNet35NotInstalled");
                        throw new NodeFailedToLaunchException(null, nodeFailedToLaunchError);
                    }
                }

                // Create the node process
                int msbuildProcessId = LaunchNode(msbuildLocation, commandLineArgs);
                _processesToIgnore.Add(GetProcessesToIgnoreKey(hostHandshake, clientHandshake, msbuildProcessId));

                // Note, when running under IMAGEFILEEXECUTIONOPTIONS registry key to debug, the process ID
                // gotten back from CreateProcess is that of the debugger, which causes this to try to connect
                // to the debugger process. Instead, use MSBUILDDEBUGONSTART=1

                // Now try to connect to it.
                NamedPipeClientStream nodeStream = TryConnectToProcess(msbuildProcessId, TimeoutForNewNodeCreation, hostHandshake, clientHandshake);
                if (nodeStream != null)
                {
                    // Connection successful, use this node.
                    CommunicationsUtilities.Trace("Successfully connected to created node {0} which is PID {1}", nodeId, msbuildProcessId);
                    return(new NodeContext(nodeId, msbuildProcessId, nodeStream, factory, terminateNode));
                }
            }

            // We were unable to launch a node.
            CommunicationsUtilities.Trace("FAILED TO CONNECT TO A CHILD NODE");
            return(null);
        }
Пример #13
0
        /// <summary>
        /// Instructs the MSBuild engine to build one or more project files whose locations are specified by the
        /// <see cref="Projects"/> property.
        /// </summary>
        /// <returns>true if all projects build successfully; false if any project fails</returns>
        public async Task <bool> ExecuteInternal()
        {
            // If no projects were passed in, just return success.
            if ((Projects == null) || (Projects.Length == 0))
            {
                return(true);
            }

            // We have been asked to unescape all escaped characters before processing
            if (this.TargetAndPropertyListSeparators != null && this.TargetAndPropertyListSeparators.Length > 0)
            {
                ExpandAllTargetsAndProperties();
            }

            // Parse the global properties into a hashtable.
            Hashtable propertiesTable;

            if (!PropertyParser.GetTableWithEscaping(Log, ResourceUtilities.FormatResourceString("General.GlobalProperties"), "Properties", this.Properties, out propertiesTable))
            {
                return(false);
            }

            // Parse out the properties to undefine, if any.
            string[] undefinePropertiesArray = null;
            if (!String.IsNullOrEmpty(_undefineProperties))
            {
                Log.LogMessageFromResources(MessageImportance.Low, "General.UndefineProperties");
                undefinePropertiesArray = _undefineProperties.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (string property in undefinePropertiesArray)
                {
                    Log.LogMessageFromText(String.Format(CultureInfo.InvariantCulture, "  {0}", property), MessageImportance.Low);
                }
            }

            bool isRunningMultipleNodes = BuildEngine2.IsRunningMultipleNodes;

            // If we are in single proc mode and stopOnFirstFailure is true, we cannot build in parallel because
            // building in parallel sends all of the projects to the engine at once preventing us from not sending
            // any more projects after the first failure. Therefore, to preserve compatibility with whidbey if we are in this situation disable buildInParallel.
            if (!isRunningMultipleNodes && _stopOnFirstFailure && _buildInParallel)
            {
                _buildInParallel = false;
                Log.LogMessageFromResources(MessageImportance.Low, "MSBuild.NotBuildingInParallel");
            }

            // When the condition below is met, provide an information message indicating stopOnFirstFailure
            // will have no effect. The reason there will be no effect is, when buildInParallel is true
            // All project files will be submitted to the engine all at once, this mean there is no stopping for failures between projects.
            // When RunEachTargetSeparately is false, all targets will be submitted to the engine at once, this means there is no way to stop between target failures.
            // therefore the first failure seen will be the only failure seen.
            if (isRunningMultipleNodes && _buildInParallel && _stopOnFirstFailure && !_runEachTargetSeparately)
            {
                Log.LogMessageFromResources(MessageImportance.Low, "MSBuild.NoStopOnFirstFailure");
            }

            // This is a list of string[].  That is, each element in the list is a string[].  Each
            // string[] represents a set of target names to build.  Depending on the value
            // of the RunEachTargetSeparately parameter, we each just call the engine to run all
            // the targets together, or we call the engine separately for each target.
            ArrayList targetLists = CreateTargetLists(this.Targets, this.RunEachTargetSeparately);


            bool success = true;

            ITaskItem[] singleProject = null;
            bool[]      skipProjects  = null;


            if (_buildInParallel)
            {
                skipProjects = new bool[Projects.Length];
                for (int i = 0; i < skipProjects.Length; i++)
                {
                    skipProjects[i] = true;
                }
            }
            else
            {
                singleProject = new ITaskItem[1];
            }

            // Read in each project file.  If there are any errors opening the file or parsing the XML,
            // raise an event and return False.  If any one of the projects fails to build, return False,
            // otherwise return True. If parallel build is requested we first check for file existence so
            // that we don't pass a non-existent file to IBuildEngine causing an exception
            for (int i = 0; i < Projects.Length; i++)
            {
                ITaskItem project = Projects[i];

                string projectPath = FileUtilities.AttemptToShortenPath(project.ItemSpec);

                if (_stopOnFirstFailure && !success)
                {
                    // Inform the user that we skipped the remaining projects because StopOnFirstFailure=true.
                    Log.LogMessageFromResources(MessageImportance.Low, "MSBuild.SkippingRemainingProjects");

                    // We have encountered a failure.  Caller has requested that we not
                    // continue with remaining projects.
                    break;
                }

                if (File.Exists(projectPath) || (_skipNonexistentProjects == SkipNonexistentProjectsBehavior.Build))
                {
                    if (FileUtilities.IsVCProjFilename(projectPath))
                    {
                        Log.LogErrorWithCodeFromResources("MSBuild.ProjectUpgradeNeededToVcxProj", project.ItemSpec);
                        success = false;
                        continue;
                    }

                    // If we are building in parallel we want to only make one call to
                    // ExecuteTargets once we verified that all projects exist
                    if (!_buildInParallel)
                    {
                        singleProject[0] = project;
                        bool executeResult = await ExecuteTargets(
                            singleProject,
                            propertiesTable,
                            undefinePropertiesArray,
                            targetLists,
                            StopOnFirstFailure,
                            RebaseOutputs,
                            BuildEngine3,
                            Log,
                            _targetOutputs,
                            _useResultsCache,
                            _unloadProjectsOnCompletion,
                            ToolsVersion
                            );

                        if (!executeResult)
                        {
                            success = false;
                        }
                    }
                    else
                    {
                        skipProjects[i] = false;
                    }
                }
                else
                {
                    if (_skipNonexistentProjects == SkipNonexistentProjectsBehavior.Skip)
                    {
                        Log.LogMessageFromResources(MessageImportance.High, "MSBuild.ProjectFileNotFoundMessage", project.ItemSpec);
                    }
                    else
                    {
                        ErrorUtilities.VerifyThrow(_skipNonexistentProjects == SkipNonexistentProjectsBehavior.Error, "skipNonexistentProjects has unexpected value {0}", _skipNonexistentProjects);
                        Log.LogErrorWithCodeFromResources("MSBuild.ProjectFileNotFound", project.ItemSpec);
                        success = false;
                    }
                }
            }

            // We need to build all the projects that were not skipped
            if (_buildInParallel)
            {
                success = await BuildProjectsInParallel(propertiesTable, undefinePropertiesArray, targetLists, success, skipProjects);
            }

            return(success);
        }
Пример #14
0
        /// <summary>
        /// Reads a plan for the specified submission Id.
        /// </summary>
        public void ReadPlan(int submissionId, ILoggingService loggingService, BuildEventContext buildEventContext)
        {
            if (!BuildParameters.EnableBuildPlan)
            {
                return;
            }

            SchedulableRequest rootRequest = GetRootRequest(submissionId);

            if (rootRequest == null)
            {
                return;
            }

            string planName = GetPlanName(rootRequest);

            if (String.IsNullOrEmpty(planName))
            {
                return;
            }

            if (!File.Exists(planName))
            {
                return;
            }

            try
            {
                using (StreamReader file = new StreamReader(File.Open(planName, FileMode.Open)))
                {
                    ReadTimes(file);
                    ReadHierarchy(file);
                }

                if (_configIdToData.Count > 0)
                {
                    AnalyzeData();
                }
            }
            catch (IOException)
            {
                loggingService.LogCommentFromText(buildEventContext, MessageImportance.Low, ResourceUtilities.FormatResourceString("CantReadBuildPlan", planName));
            }
            catch (InvalidDataException)
            {
                loggingService.LogCommentFromText(buildEventContext, MessageImportance.Low, ResourceUtilities.FormatResourceString("BuildPlanCorrupt", planName));
            }
            catch (FormatException)
            {
                loggingService.LogCommentFromText(buildEventContext, MessageImportance.Low, ResourceUtilities.FormatResourceString("BuildPlanCorrupt", planName));
            }
        }
Пример #15
0
        private void VerifyImplementationArchitecture(string winmdName, string targetProcessorArchitecture, string implementationFileArch, string warnOrErrorOnTargetArchitectureMismatch)
        {
            // Create the engine.
            MockEngine engine = new MockEngine();
            TaskItem   item   = new TaskItem(winmdName);

            ITaskItem[] assemblyFiles = new TaskItem[] { item };

            ResolveAssemblyReference t = new ResolveAssemblyReference();

            t.BuildEngine = engine;
            t.Assemblies  = assemblyFiles;
            t.SearchPaths = new String[] { @"C:\WinMDArchVerification" };
            t.TargetProcessorArchitecture             = targetProcessorArchitecture;
            t.WarnOrErrorOnTargetArchitectureMismatch = warnOrErrorOnTargetArchitectureMismatch;

            bool succeeded = Execute(t);

            Assert.Equal(1, t.ResolvedFiles.Length);

            Assert.True(t.ResolvedFiles[0].ItemSpec.Equals(@"C:\WinMDArchVerification\" + winmdName + ".winmd", StringComparison.OrdinalIgnoreCase));
            Assert.True(t.ResolvedFiles[0].GetMetadata(ItemMetadataNames.imageRuntime).Equals(@"WindowsRuntime 1.0", StringComparison.OrdinalIgnoreCase));
            Assert.True(bool.Parse(t.ResolvedFiles[0].GetMetadata(ItemMetadataNames.winMDFile)));

            string fullMessage = null;

            if (implementationFileArch.Equals("Unknown"))
            {
                fullMessage = ResourceUtilities.FormatResourceString("ResolveAssemblyReference.UnknownProcessorArchitecture", @"C:\WinMDArchVerification\" + winmdName + ".dll", @"C:\WinMDArchVerification\" + winmdName + ".winmd", NativeMethods.IMAGE_FILE_MACHINE_R4000.ToString("X", CultureInfo.InvariantCulture));
            }
            else
            {
                fullMessage = ResourceUtilities.FormatResourceString("ResolveAssemblyReference.MismatchBetweenTargetedAndReferencedArchOfImplementation", targetProcessorArchitecture, implementationFileArch, @"C:\WinMDArchVerification\" + winmdName + ".dll", @"C:\WinMDArchVerification\" + winmdName + ".winmd");
            }

            if (warnOrErrorOnTargetArchitectureMismatch.Equals("None", StringComparison.OrdinalIgnoreCase))
            {
                engine.AssertLogDoesntContain(fullMessage);
            }
            else
            {
                engine.AssertLogContains(fullMessage);
            }

            if (warnOrErrorOnTargetArchitectureMismatch.Equals("Warning", StringComparison.OrdinalIgnoreCase))
            {
                // Should fail since PE Header is not valid and this is always an error.
                Assert.True(succeeded);
                Assert.True(t.ResolvedFiles[0].GetMetadata(ItemMetadataNames.winmdImplmentationFile).Equals(winmdName + ".dll"));
                Assert.Equal(0, engine.Errors);
                Assert.Equal(1, engine.Warnings);
            }
            else if (warnOrErrorOnTargetArchitectureMismatch.Equals("Error", StringComparison.OrdinalIgnoreCase))
            {
                // Should fail since PE Header is not valid and this is always an error.
                Assert.False(succeeded);
                Assert.Equal(0, t.ResolvedFiles[0].GetMetadata(ItemMetadataNames.winmdImplmentationFile).Length);
                Assert.Equal(1, engine.Errors);
                Assert.Equal(0, engine.Warnings);
            }
            else if (warnOrErrorOnTargetArchitectureMismatch.Equals("None", StringComparison.OrdinalIgnoreCase))
            {
                Assert.True(succeeded);
                Assert.True(t.ResolvedFiles[0].GetMetadata(ItemMetadataNames.winmdImplmentationFile).Equals(winmdName + ".dll"));
                Assert.Equal(0, engine.Errors);
                Assert.Equal(0, engine.Warnings);
            }
        }
Пример #16
0
        private string GenerateCode(out string extension)
        {
            extension = null;
            bool haveGeneratedContent = false;

            CodeDomProvider provider;

            try
            {
                provider = CodeDomProvider.CreateProvider(Language);
            }
            catch (System.Configuration.ConfigurationException ex)
            {
                Log.LogErrorWithCodeFromResources("WriteCodeFragment.CouldNotCreateProvider", Language, ex.Message);
                return(null);
            }
            catch (SecurityException ex)
            {
                Log.LogErrorWithCodeFromResources("WriteCodeFragment.CouldNotCreateProvider", Language, ex.Message);
                return(null);
            }

            extension = provider.FileExtension;

            CodeCompileUnit unit = new CodeCompileUnit();

            CodeNamespace globalNamespace = new CodeNamespace();

            unit.Namespaces.Add(globalNamespace);

            // Declare authorship. Unfortunately CodeDOM puts this comment after the attributes.
            string comment = ResourceUtilities.FormatResourceString("WriteCodeFragment.Comment");

            globalNamespace.Comments.Add(new CodeCommentStatement(comment));

            if (AssemblyAttributes == null)
            {
                return(String.Empty);
            }

            // For convenience, bring in the namespaces, where many assembly attributes lie
            globalNamespace.Imports.Add(new CodeNamespaceImport("System"));
            globalNamespace.Imports.Add(new CodeNamespaceImport("System.Reflection"));

            foreach (ITaskItem attributeItem in AssemblyAttributes)
            {
                CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(new CodeTypeReference(attributeItem.ItemSpec));

                // Some attributes only allow positional constructor arguments, or the user may just prefer them.
                // To set those, use metadata names like "_Parameter1", "_Parameter2" etc.
                // If a parameter index is skipped, it's an error.
                IDictionary customMetadata = attributeItem.CloneCustomMetadata();

                List <CodeAttributeArgument> orderedParameters = new List <CodeAttributeArgument>(new CodeAttributeArgument[customMetadata.Count + 1] /* max possible slots needed */);
                List <CodeAttributeArgument> namedParameters   = new List <CodeAttributeArgument>();

                foreach (DictionaryEntry entry in customMetadata)
                {
                    string name  = (string)entry.Key;
                    string value = (string)entry.Value;

                    if (name.StartsWith("_Parameter", StringComparison.OrdinalIgnoreCase))
                    {
                        int index;

                        if (!Int32.TryParse(name.Substring("_Parameter".Length), out index))
                        {
                            Log.LogErrorWithCodeFromResources("General.InvalidValue", name, "WriteCodeFragment");
                            return(null);
                        }

                        if (index > orderedParameters.Count || index < 1)
                        {
                            Log.LogErrorWithCodeFromResources("WriteCodeFragment.SkippedNumberedParameter", index);
                            return(null);
                        }

                        // "_Parameter01" and "_Parameter1" would overwrite each other
                        orderedParameters[index - 1] = new CodeAttributeArgument(String.Empty, new CodePrimitiveExpression(value));
                    }
                    else
                    {
                        namedParameters.Add(new CodeAttributeArgument(name, new CodePrimitiveExpression(value)));
                    }
                }

                bool encounteredNull = false;
                for (int i = 0; i < orderedParameters.Count; i++)
                {
                    if (orderedParameters[i] == null)
                    {
                        // All subsequent args should be null, else a slot was missed
                        encounteredNull = true;
                        continue;
                    }

                    if (encounteredNull)
                    {
                        Log.LogErrorWithCodeFromResources("WriteCodeFragment.SkippedNumberedParameter", i + 1 /* back to 1 based */);
                        return(null);
                    }

                    attribute.Arguments.Add(orderedParameters[i]);
                }

                foreach (CodeAttributeArgument namedParameter in namedParameters)
                {
                    attribute.Arguments.Add(namedParameter);
                }

                unit.AssemblyCustomAttributes.Add(attribute);
                haveGeneratedContent = true;
            }

            StringBuilder generatedCode = new StringBuilder();

            using (StringWriter writer = new StringWriter(generatedCode, CultureInfo.CurrentCulture))
            {
                provider.GenerateCodeFromCompileUnit(unit, writer, new CodeGeneratorOptions());
            }

            string code = generatedCode.ToString();

            // If we just generated infrastructure, don't bother returning anything
            // as there's no point writing the file
            return(haveGeneratedContent ? code : String.Empty);
        }
        /// <summary>
        /// Initializes the logger by subscribing to events of IEventSource
        /// </summary>
        public void Initialize(IEventSource eventSource)
        {
            _initialTargetOutputLogging = Environment.GetEnvironmentVariable("MSBUILDTARGETOUTPUTLOGGING");
            _initialLogImports          = Environment.GetEnvironmentVariable("MSBUILDLOGIMPORTS");

            Environment.SetEnvironmentVariable("MSBUILDTARGETOUTPUTLOGGING", "true");
            Environment.SetEnvironmentVariable("MSBUILDLOGIMPORTS", "1");

            ProcessParameters();

            try
            {
                string logDirectory = null;
                try
                {
                    logDirectory = Path.GetDirectoryName(FilePath);
                }
                catch (Exception)
                {
                    // Directory creation is best-effort; if finding its path fails don't create the directory
                    // and possibly let the FileStream constructor below report the failure
                }

                if (logDirectory != null)
                {
                    Directory.CreateDirectory(logDirectory);
                }

                stream = new FileStream(FilePath, FileMode.Create);

                if (CollectProjectImports != ProjectImportsCollectionMode.None)
                {
                    projectImportsCollector = new ProjectImportsCollector(FilePath, CollectProjectImports == ProjectImportsCollectionMode.ZipFile);
                }

                if (eventSource is IEventSource3 eventSource3)
                {
                    eventSource3.IncludeEvaluationMetaprojects();
                }
            }
            catch (Exception e)
            {
                string errorCode;
                string helpKeyword;
                string message = ResourceUtilities.FormatResourceString(out errorCode, out helpKeyword, "InvalidFileLoggerFile", FilePath, e.Message);
                throw new LoggerException(message, e, errorCode, helpKeyword);
            }

            stream = new GZipStream(stream, CompressionLevel.Optimal);

            // wrapping the GZipStream in a buffered stream significantly improves performance
            // and the max throughput is reached with a 32K buffer. See details here:
            // https://github.com/dotnet/runtime/issues/39233#issuecomment-745598847
            stream          = new BufferedStream(stream, bufferSize: 32768);
            binaryWriter    = new BinaryWriter(stream);
            eventArgsWriter = new BuildEventArgsWriter(binaryWriter);

            binaryWriter.Write(FileFormatVersion);

            LogInitialInfo();

            eventSource.AnyEventRaised += EventSource_AnyEventRaised;
        }
        /// <summary>
        /// Reads the settings for a specified tools version
        /// </summary>
        /// <param name="toolsVersion"></param>
        /// <param name="globalProperties"></param>
        /// <param name="initialProperties"></param>
        /// <param name="accumulateProperties"></param>
        /// <returns></returns>
        private Toolset ReadToolset(PropertyDefinition toolsVersion,
                                    BuildPropertyGroup globalProperties,
                                    BuildPropertyGroup 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;
            BuildPropertyGroup properties = new BuildPropertyGroup();

            IEnumerable <PropertyDefinition> rawProperties = GetPropertyDefinitions(toolsVersion.Name);
            Expander expander = new Expander(initialProperties);

            foreach (PropertyDefinition property in rawProperties)
            {
                if (String.Equals(property.Name, ReservedPropertyNames.toolsPath, StringComparison.OrdinalIgnoreCase))
                {
                    toolsPath = ExpandProperty(property, expander);
                    toolsPath = ExpandRelativePathsRelativeToExeLocation(toolsPath);

                    if (accumulateProperties)
                    {
                        SetProperty
                        (
                            new PropertyDefinition(ReservedPropertyNames.toolsPath, toolsPath, property.Source),
                            initialProperties,
                            globalProperties
                        );
                    }
                }
                else if (String.Equals(property.Name, ReservedPropertyNames.binPath, StringComparison.OrdinalIgnoreCase))
                {
                    binPath = ExpandProperty(property, expander);
                    binPath = ExpandRelativePathsRelativeToExeLocation(binPath);

                    if (accumulateProperties)
                    {
                        SetProperty
                        (
                            new PropertyDefinition(ReservedPropertyNames.binPath, binPath, property.Source),
                            initialProperties,
                            globalProperties
                        );
                    }
                }
                else if (ReservedPropertyNames.IsReservedProperty(property.Name))
                {
                    // We don't allow toolsets to define reserved properties
                    string baseMessage = ResourceUtilities.FormatResourceString("CannotModifyReservedProperty", property.Name);
                    InvalidToolsetDefinitionException.Throw("InvalidPropertyNameInToolset", property.Name, property.Source, baseMessage);
                }
                else
                {
                    // It's an arbitrary property
                    string             propertyValue    = ExpandProperty(property, expander);
                    PropertyDefinition expandedProperty = new PropertyDefinition(property.Name, propertyValue, property.Source);

                    SetProperty(expandedProperty, properties, globalProperties);

                    if (accumulateProperties)
                    {
                        SetProperty(expandedProperty, initialProperties, globalProperties);
                    }
                }

                if (accumulateProperties)
                {
                    expander = new Expander(initialProperties);
                }
            }

            // All tools versions must specify a value for MSBuildToolsPath (or MSBuildBinPath)
            if (String.IsNullOrEmpty(toolsPath) && String.IsNullOrEmpty(binPath))
            {
                InvalidToolsetDefinitionException.Throw("MSBuildToolsPathIsNotSpecified", toolsVersion.Name, toolsVersion.Source);
            }

            // If both MSBuildBinPath and MSBuildToolsPath are present, they must be the same
            if (toolsPath != null && binPath != null && !toolsPath.Equals(binPath, StringComparison.OrdinalIgnoreCase))
            {
                return(null);
            }

            Toolset toolset = null;

            try
            {
                toolset = new Toolset(toolsVersion.Name, toolsPath ?? binPath, properties);
            }
            catch (ArgumentException e)
            {
                InvalidToolsetDefinitionException.Throw("ErrorCreatingToolset", toolsVersion.Name, e.Message);
            }

            return(toolset);
        }
        /// <summary>
        /// Get the SDK.
        /// </summary>
        /// <returns>true</returns>
        public override bool Execute()
        {
            // TargetPlatformVersion and TargetPlatformIdentifier are requried to correctly look for SDKs.
            if (String.IsNullOrEmpty(TargetPlatformVersion) || String.IsNullOrEmpty(TargetPlatformIdentifier))
            {
                Log.LogErrorWithCodeFromResources("GetInstalledSDKs.TargetPlatformInformationMissing");
                return(false);
            }

            // Dictionary of ESDKs. Each entry is a (location, platform version) tuple
            IDictionary <string, Tuple <string, string> > installedSDKs = null;

            try
            {
                Log.LogMessageFromResources("GetInstalledSDKs.SearchingForSDKs", _targetPlatformIdentifier, _targetPlatformVersion);

                Version platformVersion = Version.Parse(TargetPlatformVersion);
                installedSDKs = ToolLocationHelper.GetPlatformExtensionSDKLocationsAndVersions(SDKDirectoryRoots, SDKExtensionDirectoryRoots, SDKRegistryRoot, TargetPlatformIdentifier, platformVersion);
            }
            catch (Exception e)
            {
                if (ExceptionHandling.IsCriticalException(e))
                {
                    throw;
                }

                Log.LogErrorWithCodeFromResources("GetInstalledSDKs.CouldNotGetSDKList", e.Message);
            }

            List <ITaskItem> outputItems = new List <ITaskItem>();

            if (installedSDKs != null && installedSDKs.Count > 0)
            {
                Log.LogMessageFromResources(MessageImportance.Low, "GetInstalledSDKs.FoundSDKs", installedSDKs.Count);
                Log.LogMessageFromResources(MessageImportance.Low, "GetInstalledSDKs.ListInstalledSDKs");

                foreach (KeyValuePair <string, Tuple <string, string> > sdk in installedSDKs)
                {
                    string sdkInfo = ResourceUtilities.FormatResourceString("GetInstalledSDKs.SDKNameAndLocation", sdk.Key, sdk.Value.Item1);
                    Log.LogMessageFromResources(MessageImportance.Low, "ResolveAssemblyReference.FourSpaceIndent", sdkInfo);

                    TaskItem item = new TaskItem(sdk.Value.Item1);
                    item.SetMetadata("SDKName", sdk.Key);
                    item.SetMetadata("PlatformVersion", sdk.Value.Item2);

                    // Need to stash these so we can unroll the platform via GetMatchingPlatformSDK when we get the reference files for the sdks
                    item.SetMetadata(DirectoryRootsMetadataName, String.Join(";", SDKDirectoryRoots ?? new string[0]));
                    item.SetMetadata(ExtensionDirectoryRootsMetadataName, String.Join(";", SDKExtensionDirectoryRoots ?? new string[0]));
                    item.SetMetadata(RegistryRootMetadataName, SDKRegistryRoot);

                    outputItems.Add(item);
                }
            }
            else
            {
                Log.LogWarningWithCodeFromResources("GetInstalledSDKs.NoSDksFound");
            }

            InstalledSDKs = outputItems.ToArray();

            // We need to register an object so that at the end of the build we will clear the static toolLocationhelper caches.
            // this is important because if someone adds an SDK between builds we would not know about it and not be able to use it.
            // This code is mainly used to deal with the case where msbuild nodes hang around between builds.
            IBuildEngine4 buildEngine4 = BuildEngine as IBuildEngine4;

            if (buildEngine4 != null)
            {
                object staticCacheDisposer = buildEngine4.GetRegisteredTaskObject(StaticSDKCacheKey, RegisteredTaskObjectLifetime.Build);
                if (staticCacheDisposer == null)
                {
                    BuildCacheDisposeWrapper staticDisposer = new BuildCacheDisposeWrapper(new BuildCacheDisposeWrapper.CallDuringDispose(ToolLocationHelper.ClearSDKStaticCache));
                    buildEngine4.RegisterTaskObject(StaticSDKCacheKey, staticDisposer, RegisteredTaskObjectLifetime.Build, allowEarlyCollection: false);
                }
            }

            return(!Log.HasLoggedErrors);
        }
Пример #20
0
        /// <summary>
        /// Load content of Platform.xml
        /// </summary>
        private void LoadManifestFile()
        {
            /*
             * Platform.xml format:
             *
             * <ApplicationPlatform name="UAP" friendlyName="Universal Application Platform" version="1.0.0.0">
             *    <DependentPlatform name="UAP" version="1.0.0.0" />
             *    <ContainedApiContracts>
             *       <ApiContract name="UAP" version="1.0.0.0" />
             *    </ContainedApiContracts>
             * </ApplicationPlatform>
             */
            try
            {
                string platformManifestPath = Path.Combine(_pathToManifest, "Platform.xml");

                if (File.Exists(platformManifestPath))
                {
                    XmlDocument       doc            = new XmlDocument();
                    XmlReaderSettings readerSettings = new XmlReaderSettings {
                        DtdProcessing = DtdProcessing.Ignore
                    };

                    using (XmlReader xmlReader = XmlReader.Create(platformManifestPath, readerSettings))
                    {
                        doc.Load(xmlReader);
                    }

                    XmlElement rootElement = null;

                    foreach (XmlNode childNode in doc.ChildNodes)
                    {
                        if (childNode.NodeType == XmlNodeType.Element &&
                            string.Equals(childNode.Name, Elements.ApplicationPlatform, StringComparison.Ordinal))
                        {
                            rootElement = (XmlElement)childNode;
                            break;
                        }
                    }

                    DependentPlatforms = new List <DependentPlatform>();
                    ApiContracts       = new List <ApiContract>();

                    if (rootElement != null)
                    {
                        Name            = rootElement.GetAttribute(Attributes.Name);
                        FriendlyName    = rootElement.GetAttribute(Attributes.FriendlyName);
                        PlatformVersion = rootElement.GetAttribute(Attributes.Version);

                        foreach (XmlNode childNode in rootElement.ChildNodes)
                        {
                            if (!(childNode is XmlElement childElement))
                            {
                                continue;
                            }

                            if (ApiContract.IsContainedApiContractsElement(childElement.Name))
                            {
                                ApiContract.ReadContractsElement(childElement, ApiContracts);
                            }
                            else if (ApiContract.IsVersionedContentElement(childElement.Name))
                            {
                                bool.TryParse(childElement.InnerText, out bool versionedContent);
                                VersionedContent = versionedContent;
                            }
                            else if (string.Equals(childElement.Name, Elements.DependentPlatform, StringComparison.Ordinal))
                            {
                                DependentPlatforms.Add(new DependentPlatform(childElement.GetAttribute(Attributes.Name), childElement.GetAttribute(Attributes.Version)));
                            }
                        }
                    }
                }
                else
                {
                    ReadErrorMessage = ResourceUtilities.FormatResourceString("PlatformManifest.MissingPlatformXml", platformManifestPath);
                }
            }
            catch (Exception e)
            {
                if (ExceptionHandling.IsCriticalException(e))
                {
                    throw;
                }

                ReadErrorMessage = e.Message;
            }
        }
Пример #21
0
        /// <summary>
        /// Generates the code into a string.
        /// If it fails, logs an error and returns null.
        /// If no meaningful code is generated, returns empty string.
        /// Returns the default language extension as an out parameter.
        /// </summary>
        private string GenerateCodeCoreClr(out string extension)
        {
            extension = null;
            bool haveGeneratedContent = false;

            StringBuilder code = new StringBuilder();

            switch (Language.ToLowerInvariant())
            {
            case "c#":
                if (AssemblyAttributes == null)
                {
                    return(string.Empty);
                }

                extension = "cs";
                code.AppendLine("//------------------------------------------------------------------------------");
                code.AppendLine("// <auto-generated>");
                code.AppendLine("//     " + ResourceUtilities.FormatResourceString("WriteCodeFragment.Comment"));
                code.AppendLine("// </auto-generated>");
                code.AppendLine("//------------------------------------------------------------------------------");
                code.AppendLine();
                code.AppendLine("using System;");
                code.AppendLine("using System.Reflection;");
                code.AppendLine();

                foreach (ITaskItem attributeItem in AssemblyAttributes)
                {
                    string args = GetAttributeArguments(attributeItem, "=", QuoteSnippetStringCSharp);
                    if (args == null)
                    {
                        return(null);
                    }

                    code.AppendLine(string.Format($"[assembly: {attributeItem.ItemSpec}({args})]"));
                    haveGeneratedContent = true;
                }

                break;

            case "visual basic":
            case "visualbasic":
            case "vb":
                if (AssemblyAttributes == null)
                {
                    return(string.Empty);
                }

                extension = "vb";
                code.AppendLine("'------------------------------------------------------------------------------");
                code.AppendLine("' <auto-generated>");
                code.AppendLine("'     " + ResourceUtilities.FormatResourceString("WriteCodeFragment.Comment"));
                code.AppendLine("' </auto-generated>");
                code.AppendLine("'------------------------------------------------------------------------------");
                code.AppendLine();
                code.AppendLine("Option Strict Off");
                code.AppendLine("Option Explicit On");
                code.AppendLine();
                code.AppendLine("Imports System");
                code.AppendLine("Imports System.Reflection");

                foreach (ITaskItem attributeItem in AssemblyAttributes)
                {
                    string args = GetAttributeArguments(attributeItem, ":=", QuoteSnippetStringVisualBasic);
                    if (args == null)
                    {
                        return(null);
                    }

                    code.AppendLine(string.Format($"<Assembly: {attributeItem.ItemSpec}({args})>"));
                    haveGeneratedContent = true;
                }
                break;

            default:
                Log.LogErrorWithCodeFromResources("WriteCodeFragment.CouldNotCreateProvider", Language, string.Empty);
                return(null);
            }

            // If we just generated infrastructure, don't bother returning anything
            // as there's no point writing the file
            return(haveGeneratedContent ? code.ToString() : string.Empty);
        }
Пример #22
0
        /// <summary>
        ///
        /// </summary>
        /// <returns>True if the operation was successful</returns>
        internal static async Task <bool> ExecuteTargets
        (
            ITaskItem[] projects,
            Hashtable propertiesTable,
            string[] undefineProperties,
            ArrayList targetLists,
            bool stopOnFirstFailure,
            bool rebaseOutputs,
            IBuildEngine3 buildEngine,
            TaskLoggingHelper log,
            ArrayList targetOutputs,
            bool useResultsCache,
            bool unloadProjectsOnCompletion,
            string toolsVersion
        )
        {
            bool success = true;

            // We don't log a message about the project and targets we're going to
            // build, because it'll all be in the immediately subsequent ProjectStarted event.

            string[] projectDirectory = new string[projects.Length];
            string[] projectNames     = new string[projects.Length];
            string[] toolsVersions    = new string[projects.Length];
            IList <IDictionary <string, ITaskItem[]> > targetOutputsPerProject = null;

            IDictionary[]   projectProperties            = new IDictionary[projects.Length];
            List <string>[] undefinePropertiesPerProject = new List <string> [projects.Length];

            for (int i = 0; i < projectNames.Length; i++)
            {
                projectNames[i]      = null;
                projectProperties[i] = propertiesTable;

                if (projects[i] != null)
                {
                    // Retrieve projectDirectory only the first time.  It never changes anyway.
                    string projectPath = FileUtilities.AttemptToShortenPath(projects[i].ItemSpec);
                    projectDirectory[i] = Path.GetDirectoryName(projectPath);
                    projectNames[i]     = projects[i].ItemSpec;
                    toolsVersions[i]    = toolsVersion;


                    // If the user specified a different set of global properties for this project, then
                    // parse the string containing the properties
                    if (!String.IsNullOrEmpty(projects[i].GetMetadata("Properties")))
                    {
                        Hashtable preProjectPropertiesTable;
                        if (!PropertyParser.GetTableWithEscaping
                                (log, ResourceUtilities.FormatResourceString("General.OverridingProperties", projectNames[i]), "Properties", projects[i].GetMetadata("Properties").Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries),
                                out preProjectPropertiesTable)
                            )
                        {
                            return(false);
                        }

                        projectProperties[i] = preProjectPropertiesTable;
                    }

                    if (undefineProperties != null)
                    {
                        undefinePropertiesPerProject[i] = new List <string>(undefineProperties);
                    }

                    // If the user wanted to undefine specific global properties for this project, parse
                    // that string and remove them now.
                    string projectUndefineProperties = projects[i].GetMetadata("UndefineProperties");
                    if (!String.IsNullOrEmpty(projectUndefineProperties))
                    {
                        string[] propertiesToUndefine = projectUndefineProperties.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                        if (undefinePropertiesPerProject[i] == null)
                        {
                            undefinePropertiesPerProject[i] = new List <string>(propertiesToUndefine.Length);
                        }

                        if (log != null && propertiesToUndefine.Length > 0)
                        {
                            log.LogMessageFromResources(MessageImportance.Low, "General.ProjectUndefineProperties", projectNames[i]);
                            foreach (string property in propertiesToUndefine)
                            {
                                undefinePropertiesPerProject[i].Add(property);
                                log.LogMessageFromText(String.Format(CultureInfo.InvariantCulture, "  {0}", property), MessageImportance.Low);
                            }
                        }
                    }

                    // If the user specified a different set of global properties for this project, then
                    // parse the string containing the properties
                    if (!String.IsNullOrEmpty(projects[i].GetMetadata("AdditionalProperties")))
                    {
                        Hashtable additionalProjectPropertiesTable;
                        if (!PropertyParser.GetTableWithEscaping
                                (log, ResourceUtilities.FormatResourceString("General.AdditionalProperties", projectNames[i]), "AdditionalProperties", projects[i].GetMetadata("AdditionalProperties").Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries),
                                out additionalProjectPropertiesTable)
                            )
                        {
                            return(false);
                        }

                        Hashtable combinedTable = new Hashtable(StringComparer.OrdinalIgnoreCase);
                        // First copy in the properties from the global table that not in the additional properties table
                        if (projectProperties[i] != null)
                        {
                            foreach (DictionaryEntry entry in projectProperties[i])
                            {
                                if (!additionalProjectPropertiesTable.Contains(entry.Key))
                                {
                                    combinedTable.Add(entry.Key, entry.Value);
                                }
                            }
                        }
                        // Add all the additional properties
                        foreach (DictionaryEntry entry in additionalProjectPropertiesTable)
                        {
                            combinedTable.Add(entry.Key, entry.Value);
                        }
                        projectProperties[i] = combinedTable;
                    }

                    // If the user specified a different toolsVersion for this project - then override the setting
                    if (!String.IsNullOrEmpty(projects[i].GetMetadata("ToolsVersion")))
                    {
                        toolsVersions[i] = projects[i].GetMetadata("ToolsVersion");
                    }
                }
            }

            foreach (string[] targetList in targetLists)
            {
                if (stopOnFirstFailure && !success)
                {
                    // Inform the user that we skipped the remaining targets StopOnFirstFailure=true.
                    log.LogMessageFromResources(MessageImportance.Low, "MSBuild.SkippingRemainingTargets");

                    // We have encountered a failure.  Caller has requested that we not
                    // continue with remaining targets.
                    break;
                }

                // Send the project off to the build engine.  By passing in null to the
                // first param, we are indicating that the project to build is the same
                // as the *calling* project file.
                bool currentTargetResult = true;

                TaskHost          taskHost = (TaskHost)buildEngine;
                BuildEngineResult result   = await taskHost.InternalBuildProjects(projectNames, targetList, projectProperties, undefinePropertiesPerProject, toolsVersions, true /* ask that target outputs are returned in the buildengineresult */);

                currentTargetResult     = result.Result;
                targetOutputsPerProject = result.TargetOutputsPerProject;
                success = success && currentTargetResult;

                // If the engine was able to satisfy the build request
                if (currentTargetResult)
                {
                    for (int i = 0; i < projects.Length; i++)
                    {
                        IEnumerable nonNullTargetList = (targetList != null) ? targetList : targetOutputsPerProject[i].Keys;

                        foreach (string targetName in nonNullTargetList)
                        {
                            if (targetOutputsPerProject[i].ContainsKey(targetName))
                            {
                                ITaskItem[] outputItemsFromTarget = (ITaskItem[])targetOutputsPerProject[i][targetName];

                                foreach (ITaskItem outputItemFromTarget in outputItemsFromTarget)
                                {
                                    // No need to rebase if the calling project is the same as the callee project
                                    // (project == null).  Also no point in trying to copy item metadata either,
                                    // because no items were passed into the Projects parameter!
                                    if (projects[i] != null)
                                    {
                                        // Rebase the output item paths if necessary.  No need to rebase if the calling
                                        // project is the same as the callee project (project == null).
                                        if (rebaseOutputs)
                                        {
                                            try
                                            {
                                                outputItemFromTarget.ItemSpec = Path.Combine(projectDirectory[i], outputItemFromTarget.ItemSpec);
                                            }
                                            catch (ArgumentException e)
                                            {
                                                log.LogWarningWithCodeFromResources(null, projects[i].ItemSpec, 0, 0, 0, 0, "MSBuild.CannotRebaseOutputItemPath", outputItemFromTarget.ItemSpec, e.Message);
                                            }
                                        }

                                        // Copy the custom item metadata from the "Projects" items to these
                                        // output items.
                                        projects[i].CopyMetadataTo(outputItemFromTarget);

                                        // Set a metadata on the output items called "MSBuildProjectFile" which tells you which project file produced this item.
                                        if (String.IsNullOrEmpty(outputItemFromTarget.GetMetadata(ItemMetadataNames.msbuildSourceProjectFile)))
                                        {
                                            outputItemFromTarget.SetMetadata(ItemMetadataNames.msbuildSourceProjectFile, projects[i].GetMetadata(FileUtilities.ItemSpecModifiers.FullPath));
                                        }
                                    }

                                    // Set a metadata on the output items called "MSBuildTargetName" which tells you which target produced this item.
                                    if (String.IsNullOrEmpty(outputItemFromTarget.GetMetadata(ItemMetadataNames.msbuildSourceTargetName)))
                                    {
                                        outputItemFromTarget.SetMetadata(ItemMetadataNames.msbuildSourceTargetName, targetName);
                                    }
                                }

                                targetOutputs.AddRange(outputItemsFromTarget);
                            }
                        }
                    }
                }
            }

            return(success);
        }
Пример #23
0
 /// <summary>
 /// Increases the error count by 1, and logs the error message
 /// </summary>
 private void LogError(string messageResourceName, params object[] messageArgs)
 {
     ErrorLog.AddLast(ResourceUtilities.FormatResourceString(messageResourceName, messageArgs));
     ErrorCount++;
 }
Пример #24
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 = BackendNativeMethods.NORMALPRIORITYCLASS;

            startInfo.dwFlags = BackendNativeMethods.STARTFUSESTDHANDLES;

            if (String.IsNullOrEmpty(Environment.GetEnvironmentVariable("MSBUILDNODEWINDOW")))
            {
                startInfo.hStdError  = BackendNativeMethods.InvalidHandle;
                startInfo.hStdInput  = BackendNativeMethods.InvalidHandle;
                startInfo.hStdOutput = BackendNativeMethods.InvalidHandle;
                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);

#if RUNTIME_TYPE_NETCORE
            // Run the child process with the same host as the currently-running process.
            string pathToHost;
            using (Process currentProcess = Process.GetCurrentProcess()) pathToHost = currentProcess.MainModule.FileName;
            commandLineArgs = "\"" + msbuildLocation + "\" " + commandLineArgs;

            ProcessStartInfo processStartInfo = new ProcessStartInfo();
            processStartInfo.FileName        = pathToHost;
            processStartInfo.Arguments       = commandLineArgs;
            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
            BackendNativeMethods.PROCESS_INFORMATION processInfo = new BackendNativeMethods.PROCESS_INFORMATION();

            string exeName = msbuildLocation;

            bool result = BackendNativeMethods.CreateProcess
                          (
                exeName,
                commandLineArgs,
                ref processSecurityAttributes,
                ref threadSecurityAttributes,
                false,
                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);
            }

            CommunicationsUtilities.Trace("Successfully launched msbuild.exe node with PID {0}", processInfo.dwProcessId);
            return(processInfo.dwProcessId);
#endif
        }
Пример #25
0
        /// <summary>
        /// Writes a plan for the specified submission id.
        /// </summary>
        public void WritePlan(int submissionId, ILoggingService loggingService, BuildEventContext buildEventContext)
        {
            if (!BuildParameters.EnableBuildPlan)
            {
                return;
            }

            SchedulableRequest rootRequest = GetRootRequest(submissionId);

            if (rootRequest == null)
            {
                return;
            }

            string planName = GetPlanName(rootRequest);

            if (String.IsNullOrEmpty(planName))
            {
                return;
            }

            try
            {
                using (StreamWriter file = new StreamWriter(File.Open(planName, FileMode.Create)))
                {
                    // Write the accumulated configuration times.
                    Dictionary <int, double> accumulatedTimeByConfiguration = new Dictionary <int, double>();
                    RecursiveAccumulateConfigurationTimes(rootRequest, accumulatedTimeByConfiguration);

                    List <int> configurationsInOrder = new List <int>(accumulatedTimeByConfiguration.Keys);
                    configurationsInOrder.Sort();
                    foreach (int configId in configurationsInOrder)
                    {
                        file.WriteLine(String.Format(CultureInfo.InvariantCulture, "{0} {1} {2}", configId, accumulatedTimeByConfiguration[configId], _configCache[configId].ProjectFullPath));
                    }

                    file.WriteLine();

                    // Write out the dependency information.
                    RecursiveWriteDependencies(file, rootRequest);
                }
            }
            catch (IOException)
            {
                loggingService.LogCommentFromText(buildEventContext, MessageImportance.Low, ResourceUtilities.FormatResourceString("CantWriteBuildPlan", planName));
            }
        }
Пример #26
0
        /// <summary>
        /// Apply a parameter
        /// </summary>
        private void ApplyFileLoggerParameter(string parameterName, string parameterValue)
        {
            if (String.Compare("LOGFILE", parameterName, StringComparison.OrdinalIgnoreCase) == 0)
            {
                if (string.IsNullOrEmpty(parameterValue))
                {
                    string message = ResourceUtilities.FormatResourceString("InvalidFileLoggerFile", string.Empty, ResourceUtilities.FormatResourceString("logfilePathNullOrEmpty"));
                    throw new LoggerException(message);
                }

                // Set log file to the right half of the parameter string and then remove it as it is going to be replaced in Initialize
                _logFile = parameterValue;
                int indexOfParameter = _parameters.IndexOf(parameterName + s_fileLoggerParameterValueSplitCharacter[0] + parameterValue, 0, StringComparison.OrdinalIgnoreCase);
                int length           = ((string)(parameterName + s_fileLoggerParameterValueSplitCharacter[0] + parameterValue)).Length;
                // Check to see if the next char is a ; if so remove that as well
                if ((indexOfParameter + length) < _parameters.Length && _parameters[indexOfParameter + length] == ';')
                {
                    length++;
                }
                _parameters = _parameters.Remove(indexOfParameter, length);
            }
        }
        /// <summary>
        /// Writes a line from a resource string to the log, using the specified indentation.
        /// </summary>
        internal void WriteLinePrettyFromResource(int indentLevel, string resourceString, params object[] args)
        {
            string formattedString = ResourceUtilities.FormatResourceString(resourceString, args);

            WriteLinePretty(indentLevel, formattedString);
        }
Пример #28
0
            public static SdkResultBase GetSdkResult(SdkReference sdk, object nuGetVersion, SdkResolverContextBase context, SdkResultFactoryBase factory)
            {
                // Cast the NuGet version since the caller does not want to consume NuGet classes directly
                NuGetVersion parsedSdkVersion = (NuGetVersion)nuGetVersion;

                // Stores errors and warnings for the result
                ICollection <string> errors   = new List <string>();
                ICollection <string> warnings = new List <string>();

                // Load NuGet settings and a path resolver
                ISettings settings = Settings.LoadDefaultSettings(context.ProjectFilePath);

                FallbackPackagePathResolver fallbackPackagePathResolver = new FallbackPackagePathResolver(NuGetPathContext.Create(settings));

                string installedPath, installedVersion;

                // Attempt to find a package if its already installed
                if (!TryGetMSBuildSdkPackageInfo(fallbackPackagePathResolver, sdk.Name, parsedSdkVersion, out installedPath, out installedVersion))
                {
                    try
                    {
                        // Asynchronously run the restore without a commit which find the package on configured feeds, download, and unzip it without generating any other files
                        IReadOnlyList <RestoreResultPair> results = RestoreRunnerEx.RunWithoutCommit(
                            context.ProjectFilePath,
                            sdk.Name,
                            parsedSdkVersion.ToFullString(),
                            settings,
                            new NuGetSdkLogger(context.Logger, warnings, errors))
                                                                    .ConfigureAwait(continueOnCapturedContext: false)
                                                                    .GetAwaiter()
                                                                    .GetResult();

                        fallbackPackagePathResolver = new FallbackPackagePathResolver(NuGetPathContext.Create(settings));

                        // Look for a successful result, any errors are logged by NuGet
                        foreach (RestoreResult result in results.Select(i => i.Result).Where(i => i.Success))
                        {
                            // Find the information about the package that was installed.  In some cases, the version can be different than what was specified (like you specify 1.0 but get 1.0.0)
                            LibraryIdentity installedPackage = result.GetAllInstalled().FirstOrDefault(i => i.Name.Equals(sdk.Name));

                            if (installedPackage != null)
                            {
                                if (!TryGetMSBuildSdkPackageInfo(fallbackPackagePathResolver, installedPackage.Name, installedPackage.Version, out installedPath, out installedVersion))
                                {
                                    // This should never happen because we were told the package was successfully installed.
                                    // If we can't find it, we probably did something wrong with the NuGet API
                                    errors.Add(ResourceUtilities.FormatResourceString("CouldNotFindInstalledPackage", sdk));
                                }
                            }
                            else
                            {
                                // This should never happen because we were told the restore succeeded.
                                // If we can't find the package from GetAllInstalled(), we probably did something wrong with the NuGet API
                                errors.Add(ResourceUtilities.FormatResourceString("PackageWasNotInstalled", sdk, sdk.Name));
                            }
                        }
                    }
                    catch (Exception e)
                    {
                        errors.Add(e.Message);
                    }
                }

                if (errors.Count == 0)
                {
                    return(factory.IndicateSuccess(path: installedPath, version: installedVersion, warnings: warnings));
                }

                return(factory.IndicateFailure(errors, warnings));
            }