コード例 #1
0
        /// <summary>
        /// Initializes the in memory project. Sets BuildEnabled on the project to true.
        /// </summary>
        /// <param name="buildEngine">The build engine to use to create a build project.</param>
        /// <param name="fullProjectPath">The full path of the project.</param>
        /// <returns>A loaded msbuild project.</returns>
        public static Microsoft.Build.Evaluation.Project InitializeMsBuildProject(Microsoft.Build.Evaluation.ProjectCollection buildEngine, string fullProjectPath)
        {
            if (buildEngine == null)
            {
                throw new ArgumentNullException("buildEngine");
            }

            if (String.IsNullOrEmpty(fullProjectPath))
            {
                throw new ArgumentException(SR.GetString(SR.InvalidParameter, CultureInfo.CurrentUICulture), "fullProjectPath");
            }

            // Check if the project already has been loaded with the fullProjectPath. If yes return the build project associated to it.
            var prjs = new List <Microsoft.Build.Evaluation.Project>(buildEngine.GetLoadedProjects(fullProjectPath));

            System.Diagnostics.Debug.Assert(prjs.Count <= 1, string.Format("more than one loaded project with same filename '{0}'", fullProjectPath));
            Microsoft.Build.Evaluation.Project buildProject = prjs.Count == 0 ? null : prjs[0];

            if (buildProject == null)
            {
                var globalProperties = new Dictionary <string, string>()
                {
                    { "FSharpCompilerPath", Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) }
                };
                buildProject = buildEngine.LoadProject(fullProjectPath, globalProperties, null);
                buildProject.IsBuildEnabled = true;
            }

            return(buildProject);
        }
コード例 #2
0
        private static async Task <(MSB.Evaluation.Project?project, DiagnosticLog log)> LoadProjectAsync(
            string path, MSB.Evaluation.ProjectCollection?projectCollection, CancellationToken cancellationToken)
        {
            var log = new DiagnosticLog();

            try
            {
                var loadedProjects = projectCollection?.GetLoadedProjects(path);
                if (loadedProjects != null && loadedProjects.Count > 0)
                {
                    Debug.Assert(loadedProjects.Count == 1);

                    return(loadedProjects.First(), log);
                }

                using var stream     = FileUtilities.OpenAsyncRead(path);
                using var readStream = await SerializableBytes.CreateReadableStreamAsync(stream, cancellationToken).ConfigureAwait(false);

                using var xmlReader = XmlReader.Create(readStream, s_xmlReaderSettings);
                var xml = MSB.Construction.ProjectRootElement.Create(xmlReader, projectCollection);

                // When constructing a project from an XmlReader, MSBuild cannot determine the project file path.  Setting the
                // path explicitly is necessary so that the reserved properties like $(MSBuildProjectDirectory) will work.
                xml.FullPath = path;

                var project = new MSB.Evaluation.Project(xml, globalProperties: null, toolsVersion: null, projectCollection);

                return(project, log);
            }
            catch (Exception e)
            {
                log.Add(e, path);
                return(project : null, log);
            }
        }
コード例 #3
0
        private static MSB.Evaluation.Project FindProject(
            string path,
            IDictionary <string, string> globalProperties,
            MSB.Evaluation.ProjectCollection projectCollection,
            CancellationToken cancellationToken)
        {
            var loadedProjects = projectCollection.GetLoadedProjects(path);

            if (loadedProjects == null || loadedProjects.Count == 0)
            {
                return(null);
            }

            // We need to walk through all of the projects that have been previously loaded from this path and
            // find the one that has the given set of global properties, plus the default global properties that
            // we load every project with.

            globalProperties = globalProperties ?? ImmutableDictionary <string, string> .Empty;
            var totalGlobalProperties = projectCollection.GlobalProperties.Count + globalProperties.Count;

            foreach (var loadedProject in loadedProjects)
            {
                cancellationToken.ThrowIfCancellationRequested();

                // If this project has a different number of global properties than we expect, it's not the
                // one we're looking for.
                if (loadedProject.GlobalProperties.Count != totalGlobalProperties)
                {
                    continue;
                }

                // Since we loaded all of them, the projects in this collection should all have the default
                // global properties (i.e. the ones in _projectCollection.GlobalProperties). So, we just need to
                // check the extra global properties.

                var found = true;
                foreach (var(key, value) in globalProperties)
                {
                    // MSBuild escapes the values of a project's global properties, so we must too.
                    var escapedValue = MSB.Evaluation.ProjectCollection.Escape(value);

                    if (!loadedProject.GlobalProperties.TryGetValue(key, out var actualValue) ||
                        !string.Equals(actualValue, escapedValue, StringComparison.Ordinal))
                    {
                        found = false;
                        break;
                    }
                }

                if (found)
                {
                    return(loadedProject);
                }
            }

            // We couldn't find a project with this path and the set of global properties we expect.
            return(null);
        }