public ProjectCollection (IDictionary<string, string> globalProperties, IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers, ToolsetDefinitionLocations toolsetDefinitionLocations, int maxNodeCount, bool onlyLogCriticalEvents) { throw new NotImplementedException (); }
/// <summary> /// Initialize the node with the id and the callback object /// </summary> internal Node ( int nodeId, LoggerDescription[] nodeLoggers, IEngineCallback parentCallback, BuildPropertyGroup parentGlobalProperties, ToolsetDefinitionLocations toolsetSearchLocations, string parentStartupDirectory ) { this.nodeId = nodeId; this.parentCallback = parentCallback; this.exitNodeEvent = new ManualResetEvent(false); this.buildRequests = new Queue<BuildRequest>(); this.requestToLocalIdMapping = new Hashtable(); this.lastRequestIdUsed = 0; this.centralizedLogging = false; this.nodeLoggers = nodeLoggers; this.localEngine = null; this.launchedEngineLoopThread = false; this.nodeShutdown = false; this.parentGlobalProperties = parentGlobalProperties; this.toolsetSearchLocations = toolsetSearchLocations; this.parentStartupDirectory = parentStartupDirectory; }
public ProjectCollection (IDictionary<string, string> globalProperties, IEnumerable<ILogger> loggers, ToolsetDefinitionLocations toolsetDefinitionLocations) : this (globalProperties, loggers, null, toolsetDefinitionLocations, 1, false) { }
internal override void CreateFromStream(BinaryReader reader) { base.CreateFromStream(reader); #region EnvironmentVariables int numberOfVariables = reader.ReadInt32(); environmentVariables = new Hashtable(numberOfVariables); for (int i = 0; i < numberOfVariables; i++) { string key = reader.ReadString(); string variable = reader.ReadString(); environmentVariables.Add(key, variable); } #endregion #region NodeLoggers if (reader.ReadByte() == 0) { nodeLoggers = null; } else { int numberOfLoggers = reader.ReadInt32(); nodeLoggers = new LoggerDescription[numberOfLoggers]; for (int i = 0; i < numberOfLoggers; i++) { LoggerDescription logger = new LoggerDescription(); logger.CreateFromStream(reader); nodeLoggers[i] = logger; } } #endregion nodeId = reader.ReadInt32(); parentProcessId = reader.ReadInt32(); #region ParentGlobalProperties if (reader.ReadByte() == 0) { parentGlobalProperties = null; } else { parentGlobalProperties = new BuildPropertyGroup(); parentGlobalProperties.CreateFromStream(reader); } #endregion toolsetSearchLocations = (ToolsetDefinitionLocations)reader.ReadByte(); parentStartupDirectory = (string)reader.ReadString(); }
/// <summary> /// Copy constructor /// </summary> private BuildParameters(BuildParameters other) { ErrorUtilities.VerifyThrowInternalNull(other, "other"); _buildId = other._buildId; _culture = other._culture; _defaultToolsVersion = other._defaultToolsVersion; _enableNodeReuse = other._enableNodeReuse; _buildProcessEnvironment = other._buildProcessEnvironment != null ? new Dictionary<string, string>(other._buildProcessEnvironment) : null; _environmentProperties = other._environmentProperties != null ? new PropertyDictionary<ProjectPropertyInstance>(other._environmentProperties) : null; _forwardingLoggers = other._forwardingLoggers != null ? new List<ForwardingLoggerRecord>(other._forwardingLoggers) : null; _globalProperties = other._globalProperties != null ? new PropertyDictionary<ProjectPropertyInstance>(other._globalProperties) : null; _hostServices = other._hostServices; _loggers = other._loggers != null ? new List<ILogger>(other._loggers) : null; _maxNodeCount = other._maxNodeCount; _memoryUseLimit = other._memoryUseLimit; _nodeExeLocation = other._nodeExeLocation; _nodeId = other._nodeId; _onlyLogCriticalEvents = other._onlyLogCriticalEvents; _buildThreadPriority = other._buildThreadPriority; _toolsetProvider = other._toolsetProvider; _toolsetDefinitionLocations = other._toolsetDefinitionLocations; _toolsetProvider = other._toolsetProvider; _uiCulture = other._uiCulture; _detailedSummary = other._detailedSummary; _shutdownInProcNodeOnBuildFinish = other._shutdownInProcNodeOnBuildFinish; this.ProjectRootElementCache = other.ProjectRootElementCache; this.ResetCaches = other.ResetCaches; this.LegacyThreadingSemantics = other.LegacyThreadingSemantics; _saveOperatingEnvironment = other._saveOperatingEnvironment; _useSynchronousLogging = other._useSynchronousLogging; _disableInProcNode = other._disableInProcNode; _logTaskInputs = other._logTaskInputs; _logInitialPropertiesAndItems = other._logInitialPropertiesAndItems; }
/// <summary> /// Gathers toolset data from the registry and configuration file, if any: /// allows you to specify which of the registry and configuration file to /// read from by providing ToolsetInitialization /// </summary> internal static string ReadAllToolsets(Dictionary <string, Toolset> toolsets, PropertyDictionary <ProjectPropertyInstance> environmentProperties, PropertyDictionary <ProjectPropertyInstance> globalProperties, ToolsetDefinitionLocations locations) { return(ReadAllToolsets(toolsets, #if FEATURE_WIN32_REGISTRY null, #endif #if FEATURE_SYSTEM_CONFIGURATION null, #endif environmentProperties, globalProperties, locations)); }
public Engine(BuildPropertyGroup globalProperties, ToolsetDefinitionLocations locations) : this(ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version20)) { this.global_properties = globalProperties; toolsetLocations = locations; }
/// <summary> /// Gathers toolset data from the registry and configuration file, if any: /// allows you to specify which of the registry and configuration file to /// read from by providing ToolsetInitialization /// </summary> internal static string ReadAllToolsets(Dictionary<string, Toolset> toolsets, PropertyDictionary<ProjectPropertyInstance> environmentProperties, PropertyDictionary<ProjectPropertyInstance> globalProperties, ToolsetDefinitionLocations locations) { return ReadAllToolsets(toolsets, null, null, environmentProperties, globalProperties, locations); }
/// <summary> /// Gathers toolset data from the registry + configuration file + VS setup API, if any. /// NOTE: this method is internal for unit testing purposes only. /// </summary> internal static string ReadAllToolsets ( Dictionary <string, Toolset> toolsets, #if FEATURE_WIN32_REGISTRY ToolsetRegistryReader registryReader, #endif #if FEATURE_SYSTEM_CONFIGURATION ToolsetConfigurationReader configurationReader, #endif PropertyDictionary <ProjectPropertyInstance> environmentProperties, PropertyDictionary <ProjectPropertyInstance> globalProperties, ToolsetDefinitionLocations locations ) { var defaultVer = ReadAllToolsetsNative ( toolsets, #if FEATURE_WIN32_REGISTRY registryReader, #endif #if FEATURE_SYSTEM_CONFIGURATION configurationReader, #endif environmentProperties, globalProperties, locations ); const string _CUR = MSBuildConstants.CurrentToolsVersion; string currentDir = BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory.TrimEnd(Path.DirectorySeparatorChar); foreach (var vs in VisualStudioLocationHelper.GetInstances()) { string vstr = $"{vs.Version.Major}.0"; string toolbin = FileUtilities.CombinePaths ( vs.Path, "MSBuild", vs.Version.Major >= 16 ? _CUR : vstr, "Bin" ); if (IntPtr.Size == 8) { string toolbin64 = FileUtilities.CombinePaths(toolbin, "amd64"); if (Directory.Exists(toolbin64)) { toolbin = toolbin64; } } if (!toolsets.ContainsKey(vstr)) { // For Mono var buildProperties = CreateStandardProperties(globalProperties, vstr, NativeMethodsShared.FrameworkBasePath, toolbin); toolsets.Add ( vstr, new Toolset ( vstr, toolbin, buildProperties, environmentProperties, globalProperties, null, currentDir, string.Empty ) ); } } if (!toolsets.ContainsKey(_CUR)) { var actual = toolsets.GetMostActual(); if (actual != null) { toolsets.Add(_CUR, actual); } else { toolsets.Add ( _CUR, new Toolset ( _CUR, currentDir, new PropertyDictionary <ProjectPropertyInstance>(), new PropertyDictionary <ProjectPropertyInstance>(), currentDir, string.Empty ) ); } } return(defaultVer); }
/// <summary> /// Initialize the local node provider /// Only happens on the parent node. /// </summary> private void InitializeLocalNodeProvider(ToolsetDefinitionLocations locations) { // Check if the local node provider has already been initialized if (initializedLocaLNodeProvider) { return; } // Don't register a local node provider if this is a child node engine if (!Router.ChildMode && numberOfCpus > 1) { LocalNodeProvider localNodeProvider = new LocalNodeProvider(); string configuration = string.Empty; if (localNodeProviderParameters.EndsWith(";", StringComparison.OrdinalIgnoreCase)) { configuration = localNodeProviderParameters + "maxcpucount=" + Convert.ToString(numberOfCpus, CultureInfo.InvariantCulture); } else { configuration = localNodeProviderParameters + ";maxcpucount=" + Convert.ToString(numberOfCpus, CultureInfo.InvariantCulture); } localNodeProvider.Initialize(configuration, engineCallback, engineGlobalProperties, locations, startupDirectory); this.nodeManager.RegisterNodeProvider(localNodeProvider); initializedLocaLNodeProvider = true; } }
/// <summary> /// Populate ToolsetStateMap with a dictionary of (toolset version, ToolsetState) /// using information from the registry and config file, if any. /// </summary> /// <remarks>Internal for unit testing purposes only</remarks> /// <param name="locations"></param> internal void PopulateToolsetStateMap(ToolsetDefinitionLocations locations) { BuildPropertyGroup initialProperties = new BuildPropertyGroup(); initialProperties.ImportProperties(EnvironmentProperties); initialProperties.ImportProperties(GlobalProperties); string defaultVersionFromReaders = ToolsetReader.ReadAllToolsets(toolsets, GlobalProperties, initialProperties, locations); // If we got a default version from the registry or config file, we should // use that from now on. The readers guarantee that any default version they return // has a corresponding Toolset too. if (defaultVersionFromReaders != null) { this.DefaultToolsVersion = defaultVersionFromReaders; } else { // We're going to choose a hard coded default tools version of 2.0. // But don't overwrite any existing tools path for this default we're choosing. if (!toolsetStateMap.ContainsKey(Constants.defaultToolsVersion)) { string pathTo20Framework = FrameworkLocationHelper.PathToDotNetFrameworkV20; if (pathTo20Framework == null) { // We have been given no default, so we want to choose 2.0, but .NET 2.0 is not installed. // In general we do not verify that MSBuildToolsPath's point to a valid location, // so failing here would be inconsistent. The build might not even use this toolset. // Instead, synthesize what would be the path to the .NET 2.0 install location. // If the build tries to use the default toolset, the problem will be discovered then. pathTo20Framework = Path.Combine(Environment.SystemDirectory, @"Microsoft.NET\Framework\v2.0.50727"); } // There's no tools path already for 2.0, so use the path to the v2.0 .NET Framework. // If an old-fashioned caller sets BinPath property, or passed a BinPath to the constructor, // that will overwrite what we're setting here. toolsets.Add(new Toolset(Constants.defaultToolsVersion, pathTo20Framework)); } // Now update the default tools version to 2.0 DefaultToolsVersion = Constants.defaultToolsVersion; } }
/// <summary> /// Constructor used to initialize an Engine on a child node. Called only by LocalNode to create a child node's engine. /// </summary> internal Engine(BuildPropertyGroup globalProperties, ToolsetDefinitionLocations locations, int numberOfCpus, bool isChildNode, int parentNodeId, string startupDirectory, string localNodeProviderParameters) : this(numberOfCpus, isChildNode, parentNodeId, localNodeProviderParameters, globalProperties, locations) { // Override the startup directory with the one we were passed ErrorUtilities.VerifyThrow(startupDirectory != null, "Need startup directory"); this.startupDirectory = startupDirectory; forwardPropertiesFromChild = Environment.GetEnvironmentVariable("MSBuildForwardPropertiesFromChild"); // Get a list of properties which should be serialized if (!String.IsNullOrEmpty(forwardPropertiesFromChild)) { propertyListToSerialize = forwardPropertiesFromChild.Split(new char[]{';'}, StringSplitOptions.RemoveEmptyEntries); } }
/// <summary> /// Constructor to init all data except for BinPath which is initialized separately because /// a parameterless constructor is needed for COM interop /// </summary> internal Engine ( int numberOfCpus, bool isChildNode, int parentNodeId, string localNodeProviderParameters, BuildPropertyGroup globalProperties, ToolsetDefinitionLocations locations ) { // No need to check whether locations parameter // is null, because it is a value type this.startupDirectory = Environment.CurrentDirectory; this.engineGlobalProperties = globalProperties == null ? new BuildPropertyGroup() : globalProperties; this.environmentProperties = new BuildPropertyGroup(); this.toolsetStateMap = new Dictionary<string, ToolsetState>(StringComparer.OrdinalIgnoreCase); this.toolsets = new ToolsetCollection(this); // Every environment variable can be referenced just like a property // from the project file. Here, we go ahead and add all the environment // variables to the property bag, so they can be treated just like any // other property later on. this.environmentProperties.GatherEnvironmentVariables(); this.projectsLoadedByHost = new Hashtable(StringComparer.OrdinalIgnoreCase); this.cacheOfBuildingProjects = new ProjectManager(); this.eventSource = new EventSource(); this.buildEnabled = true; this.flushRequestEvent = new ManualResetEvent(false); this.primaryLoggingServices = new EngineLoggingServicesInProc(eventSource, false, flushRequestEvent); // Read any toolsets from the registry and config file PopulateToolsetStateMap(locations); this.nodeId = parentNodeId; this.localNodeProviderParameters = localNodeProviderParameters; this.numberOfCpus = numberOfCpus; if (this.numberOfCpus == 1 && !isChildNode) { this.primaryLoggingServices.FlushBuildEventsImmediatly = true; } this.buildRequests = new DualQueue<BuildRequest>(); this.taskOutputUpdates = new DualQueue<TaskExecutionContext>(); this.engineCommands = new DualQueue<EngineCommand>(); this.engineCallback = new EngineCallback(this); this.nodeManager = new NodeManager(this.numberOfCpus, isChildNode, this); this.scheduler = new Scheduler(this.nodeId, this); this.router = new Router(this, scheduler); this.cacheManager = new CacheManager(this.DefaultToolsVersion); this.lastUsedLoggerId = EngineLoggingServicesInProc.FIRST_AVAILABLE_LOGGERID; this.enabledCentralLogging = false; this.introspector = new Introspector(this, cacheOfBuildingProjects, nodeManager); // Initialize the node provider InitializeLocalNodeProvider(locations); }
/// <summary> /// Constructor used by msbuild.exe and any other multiproc aware MSBuild hosts. /// </summary> public Engine(BuildPropertyGroup globalProperties, ToolsetDefinitionLocations locations, int numberOfCpus, string localNodeProviderParameters) : this(numberOfCpus, false, 0 /* default NodeId */, localNodeProviderParameters, globalProperties, locations) { }
/// <summary> /// Constructor to specify the global properties the engine should inherit and /// the locations the engine should inspect for toolset definitions. /// </summary> public Engine(BuildPropertyGroup globalProperties, ToolsetDefinitionLocations locations) : this(1 /* cpu */, false /* not child node */, 0 /* default NodeId */, null/*No msbuild.exe path*/, globalProperties, locations) { }
/// <summary> /// Constructor to specify whether toolsets should be initialized from the msbuild configuration file and from the registry /// </summary> public Engine(ToolsetDefinitionLocations locations) : this(null, locations) { }
/// <summary> /// Constructor which will load toolsets from the specified locations. /// </summary> public ToolsetProvider(string defaultToolsVersion, PropertyDictionary<ProjectPropertyInstance> environmentProperties, PropertyDictionary<ProjectPropertyInstance> globalProperties, ToolsetDefinitionLocations toolsetDefinitionLocations) { InitializeToolsetCollection(defaultToolsVersion, environmentProperties, globalProperties, toolsetDefinitionLocations); }
/// <summary> /// This methods activates the local node /// </summary> internal void Activate ( Hashtable environmentVariables, LoggerDescription[] nodeLoggers, int nodeId, BuildPropertyGroup parentGlobalProperties, ToolsetDefinitionLocations toolsetSearchLocations, int parentId, string parentStartupDirectory ) { ErrorUtilities.VerifyThrow(node == null, "Expected node to be null on activation."); this.parentProcessId = parentId; engineCallback.Reset(); inUseEvent.Set(); // Clear the environment so that we dont have extra variables laying around, this // may be a performance hog but needs to be done IDictionary variableDictionary = Environment.GetEnvironmentVariables(); foreach (string variableName in variableDictionary.Keys) { Environment.SetEnvironmentVariable(variableName, null); } foreach(string key in environmentVariables.Keys) { Environment.SetEnvironmentVariable(key,(string)environmentVariables[key]); } // Host the msbuild engine and system node = new Node(nodeId, nodeLoggers, engineCallback, parentGlobalProperties, toolsetSearchLocations, parentStartupDirectory); // Write the initialization complete event out directly LocalCallDescriptorForInitializationComplete callDescriptor = new LocalCallDescriptorForInitializationComplete(Process.GetCurrentProcess().Id); // Post the message indicating that the initialization is complete engineCallback.PostMessageToParent(callDescriptor, true); }
/// <summary> /// Gathers toolset data from the registry and configuration file, if any: /// allows you to specify which of the registry and configuration file to /// read from by providing ToolsetInitialization /// </summary> /// <param name="toolsets"></param> /// <param name="globalProperties"></param> /// <param name="initialProperties"></param> /// <param name="locations"></param> /// <returns></returns> internal static string ReadAllToolsets(ToolsetCollection toolsets, BuildPropertyGroup globalProperties, BuildPropertyGroup initialProperties, ToolsetDefinitionLocations locations) { return ReadAllToolsets(toolsets, null, null, globalProperties, initialProperties, locations); }
/// <summary> /// Gathers toolset data from the registry and configuration file, if any: /// allows you to specify which of the registry and configuration file to /// read from by providing ToolsetInitialization /// </summary> internal static string ReadAllToolsets(Dictionary <string, Toolset> toolsets, PropertyDictionary <ProjectPropertyInstance> environmentProperties, PropertyDictionary <ProjectPropertyInstance> globalProperties, ToolsetDefinitionLocations locations) { return(ReadAllToolsets(toolsets, null, null, environmentProperties, globalProperties, locations)); }
/// <summary> /// Gathers toolset data from the registry and configuration file, if any. /// NOTE: this method is internal for unit testing purposes only. /// </summary> internal static string ReadAllToolsets ( Dictionary<string, Toolset> toolsets, ToolsetRegistryReader registryReader, ToolsetConfigurationReader configurationReader, PropertyDictionary<ProjectPropertyInstance> environmentProperties, PropertyDictionary<ProjectPropertyInstance> globalProperties, ToolsetDefinitionLocations locations ) { PropertyDictionary<ProjectPropertyInstance> initialProperties = new PropertyDictionary<ProjectPropertyInstance>(environmentProperties); initialProperties.ImportProperties(globalProperties); // The ordering here is important because the configuration file should have greater precedence // than the registry, and we do a check and don't read in the new toolset if there's already one. string defaultToolsVersionFromConfiguration = null; string overrideTasksPathFromConfiguration = null; string defaultOverrideToolsVersionFromConfiguration = null; if ((locations & ToolsetDefinitionLocations.ConfigurationFile) == ToolsetDefinitionLocations.ConfigurationFile) { if (configurationReader == null && ToolsetConfigurationReaderHelpers.ConfigurationFileMayHaveToolsets()) { // We haven't been passed in a fake configuration reader by a unit test, // and it looks like we have a .config file to read, so create a real // configuration reader configurationReader = new ToolsetConfigurationReader(environmentProperties, globalProperties); } if (configurationReader != null) { // Accumulation of properties is okay in the config file because it's deterministically ordered defaultToolsVersionFromConfiguration = configurationReader.ReadToolsets(toolsets, globalProperties, initialProperties, true /* accumulate properties */, out overrideTasksPathFromConfiguration, out defaultOverrideToolsVersionFromConfiguration); } } string defaultToolsVersionFromRegistry = null; string overrideTasksPathFromRegistry = null; string defaultOverrideToolsVersionFromRegistry = null; if ((locations & ToolsetDefinitionLocations.Registry) == ToolsetDefinitionLocations.Registry) { // If we haven't been provided a registry reader (i.e. unit tests), create one registryReader = registryReader ?? new ToolsetRegistryReader(environmentProperties, globalProperties); // We do not accumulate properties when reading them from the registry, because the order // in which values are returned to us is essentially random: so we disallow one property // in the registry to refer to another also in the registry defaultToolsVersionFromRegistry = registryReader.ReadToolsets(toolsets, globalProperties, initialProperties, false /* do not accumulate properties */, out overrideTasksPathFromRegistry, out defaultOverrideToolsVersionFromRegistry); } // The 2.0 .NET Framework installer did not write a ToolsVersion key for itself in the registry. // The 3.5 installer writes one for 2.0, but 3.5 might not be installed. // The 4.0 and subsequent installers can't keep writing the 2.0 one, because (a) it causes SxS issues and (b) we // don't want it unless 2.0 is installed. // So if the 2.0 framework is actually installed, we're reading the registry, and either the registry or the config // file have not already created the 2.0 toolset, mock up a fake one. if ( ((locations & ToolsetDefinitionLocations.Registry) != 0) && !toolsets.ContainsKey("2.0") && FrameworkLocationHelper.PathToDotNetFrameworkV20 != null ) { Toolset synthetic20Toolset = new Toolset("2.0", FrameworkLocationHelper.PathToDotNetFrameworkV20, environmentProperties, globalProperties, null /* 2.0 did not have override tasks */, null /* 2.0 did not have a default override toolsversion */); toolsets.Add("2.0", synthetic20Toolset); } // We'll use the path from the configuration file if it was specified, otherwise we'll try // the one from the registry. It's possible (and valid) that neither the configuration file // nor the registry specify a override in which case we'll just return null. string overrideTasksPath = overrideTasksPathFromConfiguration ?? overrideTasksPathFromRegistry; // We'll use the path from the configuration file if it was specified, otherwise we'll try // the one from the registry. It's possible (and valid) that neither the configuration file // nor the registry specify a override in which case we'll just return null. string defaultOverrideToolsVersion = defaultOverrideToolsVersionFromConfiguration ?? defaultOverrideToolsVersionFromRegistry; // We'll use the default from the configuration file if it was specified, otherwise we'll try // the one from the registry. It's possible (and valid) that neither the configuration file // nor the registry specify a default, in which case we'll just return null. string defaultToolsVersion = defaultToolsVersionFromConfiguration ?? defaultToolsVersionFromRegistry; // If we got a default version from the registry or config file, and it // actually exists, fine. // Otherwise we have to come up with one. if (defaultToolsVersion == null || !toolsets.ContainsKey(defaultToolsVersion)) { // We're going to choose a hard coded default tools version of 2.0. defaultToolsVersion = Constants.defaultToolsVersion; // But don't overwrite any existing tools path for this default we're choosing. if (!toolsets.ContainsKey(Constants.defaultToolsVersion)) { // There's no tools path already for 2.0, so use the path to the v2.0 .NET Framework. // If an old-fashioned caller sets BinPath property, or passed a BinPath to the constructor, // that will overwrite what we're setting here. ErrorUtilities.VerifyThrow(Constants.defaultToolsVersion == "2.0", "Getting 2.0 FX path so default should be 2.0"); string pathToFramework = FrameworkLocationHelper.PathToDotNetFrameworkV20; // We could not find the default toolsversion because it was not installed on the machine. Fallback to the // one we expect to always be there when running msbuild 4.0. if (pathToFramework == null) { pathToFramework = FrameworkLocationHelper.PathToDotNetFrameworkV40; defaultToolsVersion = Constants.defaultFallbackToolsVersion; } // Again don't overwrite any existing tools path for this default we're choosing. if (!toolsets.ContainsKey(defaultToolsVersion)) { Toolset defaultToolset = new Toolset(defaultToolsVersion, pathToFramework, environmentProperties, globalProperties, overrideTasksPath, defaultOverrideToolsVersion); toolsets.Add(defaultToolsVersion, defaultToolset); } } } return defaultToolsVersion; }
public void Initialize ( string configuration, IEngineCallback parentEngineCallback, BuildPropertyGroup parentGlobalPropertyGroup, ToolsetDefinitionLocations toolSetSearchLocations, string startupDirectory ) { // Get from the environment how long we should wait in seconds for shutdown to complete string shutdownTimeoutFromEnvironment = Environment.GetEnvironmentVariable("MSBUILDNODESHUTDOWNTIMEOUT"); int result; if (int.TryParse(shutdownTimeoutFromEnvironment, out result) && result >= 0) { shutdownTimeout = result; } this.cpuCount = 1; if (configuration != null) { // Split out the parameter sets based on ; string[] parameters; parameters = configuration.Split(parameterDelimiters); // Go through each of the parameter name value pairs and split them appart for (int param = 0; param < parameters.Length; param++) { if (parameters[param].Length > 0) { string[] parameterComponents = parameters[param].Split(valueDelimiters); // If there is a name and value associated with the parameter, apply the paramter to the provider if (parameterComponents.Length == 2) { ApplyParameter(parameterComponents[0], parameterComponents[1]); } else // Only the parameter name is known, this could be for a boolean parameter { ApplyParameter(parameters[param], null); } } } } /* If we dont get a path passed in as a parameter, we can only assume that our path * is in the current appdomain basedirectory, this is the base directory * that the assembly resolver uses to probe for assemblies */ if (string.IsNullOrEmpty(this.locationOfMSBuildExe)) { this.locationOfMSBuildExe = AppDomain.CurrentDomain.BaseDirectory; } if ((cpuCount - 1) <= 0) { return; } this.exitCommunicationThreads = new ManualResetEvent(false); this.activeNodeCount = 0; this.responseCountChangeEvent = new ManualResetEvent(false); this.nodeStateLock = new object(); this.nodesToLaunch = new Queue <int>(); this.nodeLoggers = new List <LoggerDescription>(); nodeData = new LocalNodeInfo[cpuCount - 1]; // Initialize the internal state indicating that no nodes have been launched int lastUsedNodeNumber = 0; for (int i = 0; i < nodeData.Length; i++) { nodeData[i] = new LocalNodeInfo(lastUsedNodeNumber); lastUsedNodeNumber = nodeData[i].NodeNumber + 1; } // Set up the callback this.engineCallback = parentEngineCallback; this.parentGlobalProperties = parentGlobalPropertyGroup; this.toolsetSearchLocations = toolSetSearchLocations; this.startupDirectory = startupDirectory; // Default node settings centralizedLogging = false; onlyLogCriticalEvents = false; useBreadthFirstTraversal = true; shuttingDown = false; // Start the thread that will be processing the calls from the parent engine ThreadStart threadState = new ThreadStart(this.SharedMemoryWriterThread); Thread taskThread = new Thread(threadState); taskThread.Name = "MSBuild Parent->Child Writer"; taskThread.Start(); threadState = new ThreadStart(this.SharedMemoryReaderThread); taskThread = new Thread(threadState); taskThread.Name = "MSBuild Parent<-Child Reader"; taskThread.Start(); }
/// <summary> /// Gathers toolset data from the registry and configuration file, if any. /// NOTE: this method is internal for unit testing purposes only. /// </summary> internal static string ReadAllToolsets ( Dictionary <string, Toolset> toolsets, #if FEATURE_WIN32_REGISTRY ToolsetRegistryReader registryReader, #endif #if FEATURE_SYSTEM_CONFIGURATION ToolsetConfigurationReader configurationReader, #endif PropertyDictionary <ProjectPropertyInstance> environmentProperties, PropertyDictionary <ProjectPropertyInstance> globalProperties, ToolsetDefinitionLocations locations ) { var initialProperties = new PropertyDictionary <ProjectPropertyInstance>(environmentProperties); initialProperties.ImportProperties(globalProperties); // The ordering here is important because the configuration file should have greater precedence // than the registry, and we do a check and don't read in the new toolset if there's already one. string defaultToolsVersionFromConfiguration = null; string overrideTasksPathFromConfiguration = null; string defaultOverrideToolsVersionFromConfiguration = null; #if FEATURE_SYSTEM_CONFIGURATION if ((locations & ToolsetDefinitionLocations.ConfigurationFile) == ToolsetDefinitionLocations.ConfigurationFile) { if (configurationReader == null) { configurationReader = new ToolsetConfigurationReader(environmentProperties, globalProperties); } // Accumulation of properties is okay in the config file because it's deterministically ordered defaultToolsVersionFromConfiguration = configurationReader.ReadToolsets(toolsets, globalProperties, initialProperties, true /* accumulate properties */, out overrideTasksPathFromConfiguration, out defaultOverrideToolsVersionFromConfiguration); } #endif string defaultToolsVersionFromRegistry = null; string overrideTasksPathFromRegistry = null; string defaultOverrideToolsVersionFromRegistry = null; if ((locations & ToolsetDefinitionLocations.Registry) == ToolsetDefinitionLocations.Registry) { #if FEATURE_WIN32_REGISTRY if (NativeMethodsShared.IsWindows || registryReader != null) { // If we haven't been provided a registry reader (i.e. unit tests), create one registryReader = registryReader ?? new ToolsetRegistryReader(environmentProperties, globalProperties); // We do not accumulate properties when reading them from the registry, because the order // in which values are returned to us is essentially random: so we disallow one property // in the registry to refer to another also in the registry defaultToolsVersionFromRegistry = registryReader.ReadToolsets(toolsets, globalProperties, initialProperties, false /* do not accumulate properties */, out overrideTasksPathFromRegistry, out defaultOverrideToolsVersionFromRegistry); } else #endif { var currentDir = BuildEnvironmentHelper.Instance.CurrentMSBuildToolsDirectory.TrimEnd(Path.DirectorySeparatorChar); var props = new PropertyDictionary <ProjectPropertyInstance>(); var libraryPath = NativeMethodsShared.FrameworkBasePath; if (!string.IsNullOrEmpty(libraryPath)) { // The 4.0 toolset is installed in the framework directory var v4Dir = FrameworkLocationHelper.GetPathToDotNetFrameworkV40(DotNetFrameworkArchitecture.Current); if (v4Dir != null && !toolsets.ContainsKey("4.0")) { // Create standard properties. On Mono they are well known var buildProperties = CreateStandardProperties(globalProperties, "4.0", libraryPath, v4Dir); toolsets.Add( "4.0", new Toolset( "4.0", v4Dir, buildProperties, environmentProperties, globalProperties, null, currentDir, string.Empty)); } // Other toolsets are installed in the xbuild directory var xbuildToolsetsDir = Path.Combine(libraryPath, $"xbuild{Path.DirectorySeparatorChar}"); if (FileSystems.Default.DirectoryExists(xbuildToolsetsDir)) { var r = new Regex(Regex.Escape(xbuildToolsetsDir) + @"\d+\.\d+"); foreach (var d in Directory.GetDirectories(xbuildToolsetsDir).Where(d => r.IsMatch(d))) { var version = Path.GetFileName(d); var binPath = Path.Combine(d, "bin"); if (toolsets.ContainsKey(version)) { continue; } if (NativeMethodsShared.IsMono && Version.TryParse(version, out Version parsedVersion) && parsedVersion.Major > 14) { continue; } // Create standard properties. On Mono they are well known var buildProperties = CreateStandardProperties(globalProperties, version, xbuildToolsetsDir, binPath); toolsets.Add( version, new Toolset( version, binPath, buildProperties, environmentProperties, globalProperties, null, currentDir, string.Empty)); } } } if (!toolsets.ContainsKey(MSBuildConstants.CurrentToolsVersion)) { toolsets.Add( MSBuildConstants.CurrentToolsVersion, new Toolset( MSBuildConstants.CurrentToolsVersion, currentDir, props, new PropertyDictionary <ProjectPropertyInstance>(), currentDir, string.Empty)); } } } // The 2.0 .NET Framework installer did not write a ToolsVersion key for itself in the registry. // The 3.5 installer writes one for 2.0, but 3.5 might not be installed. // The 4.0 and subsequent installers can't keep writing the 2.0 one, because (a) it causes SxS issues and (b) we // don't want it unless 2.0 is installed. // So if the 2.0 framework is actually installed, we're reading the registry, and either the registry or the config // file have not already created the 2.0 toolset, mock up a fake one. if (((locations & ToolsetDefinitionLocations.Registry) != 0) && !toolsets.ContainsKey("2.0") && FrameworkLocationHelper.PathToDotNetFrameworkV20 != null) { var synthetic20Toolset = new Toolset( "2.0", FrameworkLocationHelper.PathToDotNetFrameworkV20, environmentProperties, globalProperties, null /* 2.0 did not have override tasks */, null /* 2.0 did not have a default override toolsversion */); toolsets.Add("2.0", synthetic20Toolset); } string defaultToolsVersionFromLocal = null; string overrideTasksPathFromLocal = null; string defaultOverrideToolsVersionFromLocal = null; if ((locations & ToolsetDefinitionLocations.Local) == ToolsetDefinitionLocations.Local) { var localReader = new ToolsetLocalReader(environmentProperties, globalProperties); defaultToolsVersionFromLocal = localReader.ReadToolsets( toolsets, globalProperties, initialProperties, false /* accumulate properties */, out overrideTasksPathFromLocal, out defaultOverrideToolsVersionFromLocal); } // We'll use the path from the configuration file if it was specified, otherwise we'll try // the one from the registry. It's possible (and valid) that neither the configuration file // nor the registry specify a override in which case we'll just return null. var overrideTasksPath = overrideTasksPathFromConfiguration ?? overrideTasksPathFromRegistry ?? overrideTasksPathFromLocal; // We'll use the path from the configuration file if it was specified, otherwise we'll try // the one from the registry. It's possible (and valid) that neither the configuration file // nor the registry specify a override in which case we'll just return null. var defaultOverrideToolsVersion = defaultOverrideToolsVersionFromConfiguration ?? defaultOverrideToolsVersionFromRegistry ?? defaultOverrideToolsVersionFromLocal; // We'll use the default from the configuration file if it was specified, otherwise we'll try // the one from the registry. It's possible (and valid) that neither the configuration file // nor the registry specify a default, in which case we'll just return null. var defaultToolsVersion = defaultToolsVersionFromConfiguration ?? defaultToolsVersionFromRegistry ?? defaultToolsVersionFromLocal; // If we got a default version from the registry or config file, and it // actually exists, fine. // Otherwise we have to come up with one. if (defaultToolsVersion != null && toolsets.ContainsKey(defaultToolsVersion)) { return(defaultToolsVersion); } // We're going to choose a hard coded default tools version of 2.0. defaultToolsVersion = Constants.defaultToolsVersion; // But don't overwrite any existing tools path for this default we're choosing. if (toolsets.ContainsKey(Constants.defaultToolsVersion)) { return(defaultToolsVersion); } // There's no tools path already for 2.0, so use the path to the v2.0 .NET Framework. // If an old-fashioned caller sets BinPath property, or passed a BinPath to the constructor, // that will overwrite what we're setting here. ErrorUtilities.VerifyThrow( Constants.defaultToolsVersion == "2.0", "Getting 2.0 FX path so default should be 2.0"); var pathToFramework = FrameworkLocationHelper.PathToDotNetFrameworkV20; // We could not find the default toolsversion because it was not installed on the machine. Fallback to the // one we expect to always be there when running msbuild 4.0. if (pathToFramework == null) { pathToFramework = FrameworkLocationHelper.PathToDotNetFrameworkV40; defaultToolsVersion = Constants.defaultFallbackToolsVersion; } // Again don't overwrite any existing tools path for this default we're choosing. if (toolsets.ContainsKey(defaultToolsVersion)) { return(defaultToolsVersion); } var defaultToolset = new Toolset( defaultToolsVersion, pathToFramework, environmentProperties, globalProperties, overrideTasksPath, defaultOverrideToolsVersion); toolsets.Add(defaultToolsVersion, defaultToolset); return(defaultToolsVersion); }
/// <summary> /// Gathers toolset data from the registry and configuration file, if any. /// NOTE: this method is internal for unit testing purposes only. /// </summary> /// <param name="toolsets"></param> /// <param name="registryReader"></param> /// <param name="configurationReader"></param> /// <param name="globalProperties"></param> /// <param name="initialProperties"></param> /// <param name="locations"></param> /// <returns></returns> internal static string ReadAllToolsets(ToolsetCollection toolsets, ToolsetRegistryReader registryReader, ToolsetConfigurationReader configurationReader, BuildPropertyGroup globalProperties, BuildPropertyGroup initialProperties, ToolsetDefinitionLocations locations) { // The 2.0 .NET Framework installer did not write a ToolsVersion key for itself in the registry. // The 3.5 installer writes one for 2.0, but 3.5 might not be installed. // The 4.0 and subsequent installers can't keep writing the 2.0 one, because (a) it causes SxS issues and (b) we // don't want it unless 2.0 is installed. // So if the 2.0 framework is actually installed, and we're reading the registry, create a toolset for it. // The registry and config file can overwrite it. if ( ((locations & ToolsetDefinitionLocations.Registry) != 0) && !toolsets.Contains("2.0") && FrameworkLocationHelper.PathToDotNetFrameworkV20 != null ) { Toolset synthetic20Toolset = new Toolset("2.0", FrameworkLocationHelper.PathToDotNetFrameworkV20, initialProperties); toolsets.Add(synthetic20Toolset); } // The ordering here is important because the configuration file should have greater precedence // than the registry string defaultToolsVersionFromRegistry = null; ToolsetRegistryReader registryReaderToUse = null; if ((locations & ToolsetDefinitionLocations.Registry) == ToolsetDefinitionLocations.Registry) { registryReaderToUse = registryReader ?? new ToolsetRegistryReader(); // We do not accumulate properties when reading them from the registry, because the order // in which values are returned to us is essentially random: so we disallow one property // in the registry to refer to another also in the registry defaultToolsVersionFromRegistry = registryReaderToUse.ReadToolsets(toolsets, globalProperties, initialProperties, false /* do not accumulate properties */); } string defaultToolsVersionFromConfiguration = null; ToolsetConfigurationReader configurationReaderToUse = null; if ((locations & ToolsetDefinitionLocations.ConfigurationFile) == ToolsetDefinitionLocations.ConfigurationFile) { if (configurationReader == null && ConfigurationFileMayHaveToolsets()) { // We haven't been passed in a fake configuration reader by a unit test, // and it looks like we have a .config file to read, so create a real // configuration reader configurationReader = new ToolsetConfigurationReader(); } if (configurationReader != null) { configurationReaderToUse = configurationReader ?? new ToolsetConfigurationReader(); // Accumulation of properties is okay in the config file because it's deterministically ordered defaultToolsVersionFromConfiguration = configurationReaderToUse.ReadToolsets(toolsets, globalProperties, initialProperties, true /* accumulate properties */); } } // We'll use the default from the configuration file if it was specified, otherwise we'll try // the one from the registry. It's possible (and valid) that neither the configuration file // nor the registry specify a default, in which case we'll just return null. string defaultToolsVersion = defaultToolsVersionFromConfiguration ?? defaultToolsVersionFromRegistry; // If we got a default version from the registry or config file, and it // actually exists, fine. // Otherwise we have to come up with one. if (defaultToolsVersion == null || !toolsets.Contains(defaultToolsVersion)) { // We're going to choose a hard coded default tools version of 2.0. defaultToolsVersion = Constants.defaultToolsVersion; // But don't overwrite any existing tools path for this default we're choosing. if (!toolsets.Contains(Constants.defaultToolsVersion)) { // There's no tools path already for 2.0, so use the path to the v2.0 .NET Framework. // If an old-fashioned caller sets BinPath property, or passed a BinPath to the constructor, // that will overwrite what we're setting here. ErrorUtilities.VerifyThrow(Constants.defaultToolsVersion == "2.0", "Getting 2.0 FX path so default should be 2.0"); string pathToFramework = FrameworkLocationHelper.PathToDotNetFrameworkV20; // We could not find the default toolsversion because it was not installed on the machine. Fallback to the // one we expect to always be there when running msbuild 4.0. if (pathToFramework == null) { pathToFramework = FrameworkLocationHelper.PathToDotNetFrameworkV40; defaultToolsVersion = Constants.defaultFallbackToolsVersion; } // Again don't overwrite any existing tools path for this default we're choosing. if (!toolsets.Contains(defaultToolsVersion)) { Toolset defaultToolset = new Toolset(defaultToolsVersion, pathToFramework, initialProperties); toolsets.Add(defaultToolset); } } } return(defaultToolsVersion); }
public Engine(ToolsetDefinitionLocations locations) : this(ToolLocationHelper.GetPathToDotNetFramework(TargetDotNetFrameworkVersion.Version20)) { toolsetLocations = locations; }
/// <summary> /// Gathers toolset data from the registry and configuration file, if any: /// allows you to specify which of the registry and configuration file to /// read from by providing ToolsetInitialization /// </summary> /// <param name="toolsets"></param> /// <param name="globalProperties"></param> /// <param name="initialProperties"></param> /// <param name="locations"></param> /// <returns></returns> internal static string ReadAllToolsets(ToolsetCollection toolsets, BuildPropertyGroup globalProperties, BuildPropertyGroup initialProperties, ToolsetDefinitionLocations locations) { return(ReadAllToolsets(toolsets, null, null, globalProperties, initialProperties, locations)); }
internal LocalCallDescriptorForInitializeNode ( Hashtable environmentVariablesToSend, LoggerDescription[] nodeLoggers, int nodeId, BuildPropertyGroup parentGlobalProperties, ToolsetDefinitionLocations toolsetSearchLocations, int parentProcessId, string parentStartupDirectory ) : base(LocalCallType.InitializeNode) { this.environmentVariables = environmentVariablesToSend; this.parentGlobalProperties = parentGlobalProperties; this.toolsetSearchLocations = toolsetSearchLocations; this.nodeLoggers = nodeLoggers; this.nodeId = nodeId; this.parentProcessId = parentProcessId; this.parentStartupDirectory = parentStartupDirectory; }
private void InitializeToolsetCollection(PropertyDictionary <ProjectPropertyInstance> environmentProperties, PropertyDictionary <ProjectPropertyInstance> globalProperties, ToolsetDefinitionLocations toolsetDefinitionLocations) { _toolsets = new Dictionary <string, Toolset>(StringComparer.OrdinalIgnoreCase); ToolsetReader.ReadAllToolsets(_toolsets, environmentProperties, globalProperties, toolsetDefinitionLocations); }
/// <summary> /// Creates BuildParameters from a ProjectCollection. /// </summary> /// <param name="projectCollection">The ProjectCollection from which the BuildParameters should populate itself.</param> public BuildParameters(ProjectCollection projectCollection) { ErrorUtilities.VerifyThrowArgumentNull(projectCollection, "projectCollection"); Initialize(new PropertyDictionary<ProjectPropertyInstance>(projectCollection.EnvironmentProperties), projectCollection.ProjectRootElementCache, new ToolsetProvider(projectCollection.Toolsets)); _maxNodeCount = projectCollection.MaxNodeCount; _onlyLogCriticalEvents = projectCollection.OnlyLogCriticalEvents; _toolsetDefinitionLocations = projectCollection.ToolsetLocations; _defaultToolsVersion = projectCollection.DefaultToolsVersion; _globalProperties = new PropertyDictionary<ProjectPropertyInstance>(projectCollection.GlobalPropertiesCollection); }
void INodeProvider.Initialize(string configuration, IEngineCallback engineCallback, BuildPropertyGroup parentGlobalProperties, ToolsetDefinitionLocations toolsetSearchLocations, string startDirectory) { this.initConfiguration = configuration; this.initEngineCallback = engineCallback; this.parentGlobalProperties = parentGlobalProperties; this.toolsetSearchLocations = toolsetSearchLocations; this.startDirectory = startDirectory; }
public ProjectCollection (ToolsetDefinitionLocations toolsetDefinitionLocations) : this (null, null, toolsetDefinitionLocations) { }
public Engine(ToolsetDefinitionLocations locations) : this(ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20)) { //toolsetLocations = locations; }
public ToolsetProvider(string defaultToolsVersion, PropertyDictionary <ProjectPropertyInstance> environmentProperties, PropertyDictionary <ProjectPropertyInstance> globalProperties, ToolsetDefinitionLocations toolsetDefinitionLocations) { InitializeToolsetCollection(environmentProperties, globalProperties, toolsetDefinitionLocations); }
/// <summary> /// Populate Toolsets with a dictionary of (toolset version, Toolset) /// using information from the registry and config file, if any. /// </summary> private void InitializeToolsetCollection(string defaultToolsVersion, PropertyDictionary<ProjectPropertyInstance> environmentProperties, PropertyDictionary<ProjectPropertyInstance> globalProperties, ToolsetDefinitionLocations toolsetDefinitionLocations) { _toolsets = new Dictionary<string, Toolset>(StringComparer.OrdinalIgnoreCase); defaultToolsVersion = ToolsetReader.ReadAllToolsets(_toolsets, environmentProperties, globalProperties, toolsetDefinitionLocations); }
public ProjectCollection(ToolsetDefinitionLocations toolsetDefinitionLocations) : this(null, null, toolsetDefinitionLocations) { }
public ProjectCollection(IDictionary <string, string> globalProperties, IEnumerable <ILogger> loggers, ToolsetDefinitionLocations toolsetDefinitionLocations) : this(globalProperties, loggers, null, toolsetDefinitionLocations, 1, false) { }
public Engine(BuildPropertyGroup globalProperties, ToolsetDefinitionLocations locations) : this(ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20)) { this.global_properties = globalProperties; //toolsetLocations = locations; }
public void Initialize ( string configuration, IEngineCallback parentEngineCallback, BuildPropertyGroup parentGlobalPropertyGroup, ToolsetDefinitionLocations toolSetSearchLocations, string startupDirectory ) { // Get from the environment how long we should wait in seconds for shutdown to complete string shutdownTimeoutFromEnvironment = Environment.GetEnvironmentVariable("MSBUILDNODESHUTDOWNTIMEOUT"); int result; if (int.TryParse(shutdownTimeoutFromEnvironment, out result) && result >= 0) { shutdownTimeout = result; } this.cpuCount = 1; if (configuration != null) { // Split out the parameter sets based on ; string[] parameters; parameters = configuration.Split(parameterDelimiters); // Go through each of the parameter name value pairs and split them appart for (int param = 0; param < parameters.Length; param++) { if (parameters[param].Length > 0) { string[] parameterComponents = parameters[param].Split(valueDelimiters); // If there is a name and value associated with the parameter, apply the paramter to the provider if (parameterComponents.Length == 2) { ApplyParameter(parameterComponents[0], parameterComponents[1]); } else // Only the parameter name is known, this could be for a boolean parameter { ApplyParameter(parameters[param], null); } } } } /* If we dont get a path passed in as a parameter, we can only assume that our path is in the current appdomain basedirectory, this is the base directory that the assembly resolver uses to probe for assemblies */ if (string.IsNullOrEmpty(this.locationOfMSBuildExe)) { this.locationOfMSBuildExe = AppDomain.CurrentDomain.BaseDirectory; } if ( (cpuCount - 1) <= 0) { return; } this.exitCommunicationThreads = new ManualResetEvent(false); this.activeNodeCount = 0; this.responseCountChangeEvent = new ManualResetEvent(false); this.nodeStateLock = new object(); this.nodesToLaunch = new Queue<int>(); this.nodeLoggers = new List<LoggerDescription>(); nodeData = new LocalNodeInfo[cpuCount - 1]; // Initialize the internal state indicating that no nodes have been launched int lastUsedNodeNumber = 0; for (int i = 0; i < nodeData.Length; i++) { nodeData[i] = new LocalNodeInfo(lastUsedNodeNumber); lastUsedNodeNumber = nodeData[i].NodeNumber + 1; } // Set up the callback this.engineCallback = parentEngineCallback; this.parentGlobalProperties = parentGlobalPropertyGroup; this.toolsetSearchLocations = toolSetSearchLocations; this.startupDirectory = startupDirectory; // Default node settings centralizedLogging = false; onlyLogCriticalEvents = false; useBreadthFirstTraversal = true; shuttingDown = false; // Start the thread that will be processing the calls from the parent engine ThreadStart threadState = new ThreadStart(this.SharedMemoryWriterThread); Thread taskThread = new Thread(threadState); taskThread.Name = "MSBuild Parent->Child Writer"; taskThread.Start(); threadState = new ThreadStart(this.SharedMemoryReaderThread); taskThread = new Thread(threadState); taskThread.Name = "MSBuild Parent<-Child Reader"; taskThread.Start(); }