예제 #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);
        }
        public bool Initialize()
        {
            if (NeedsInitialization)
            {
                if (VSPackage.CoreDte.ItemOperations.PromptToSave == EnvDTE.vsPromptResult.vsPromptResultCancelled)
                {
                    return(false);
                }
                else
                {
                    UnloadProject(FullName);
                    using (var projectCollection = new Microsoft.Build.Evaluation.ProjectCollection())
                    {
                        var buildProject = projectCollection.LoadProject(FullName);
                        var targets      = buildProject.Xml.Targets;

                        if (!targets.Any(t => t.Name == "SetParametersDeploy"))
                        {
                            var target = buildProject.Xml.CreateTargetElement("SetParametersDeploy");
                            buildProject.Xml.AppendChild(target);
                            target.AfterTargets = "Package";
                            target.AddTask("MakeDir").SetParameter("Directories", "$(PackageLocation)");
                            var copyTask = target.AddTask("Copy");
                            copyTask.SetParameter("SourceFiles", "@(Parameterization)");
                            copyTask.SetParameter("DestinationFolder", "$(PackageLocation)");

                            buildProject.Xml.Save();
                        }
                    }
                    ReloadProject(FullName);
                }
            }
            return(true);
        }
예제 #3
0
        private void ResolveForNamespace(string projectDir, string projectFileName)
        {
            string proj_full_path = Path.Combine(projectDir, projectFileName);

            try
            {
                Microsoft.Build.Evaluation.ProjectCollection projCollection = new Microsoft.Build.Evaluation.ProjectCollection();
                var proj = projCollection.LoadProject(proj_full_path);
                foreach (var item in proj.Properties)
                {
                    if (item.Name == "RootNamespace")
                    {
                        this.txtNamespace.Text = item.EvaluatedValue;
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                string ns = ReadNamespaceFromProjectXml(proj_full_path);
                if (string.IsNullOrEmpty(ns))
                {
                    LogText(string.Format("{0}{1}{5}  错误信息:{2}{3},堆栈信息:{4}", Environment.NewLine, DateTime.Now.ToString(), ex.Message, Environment.NewLine, ex.StackTrace, proj_full_path));
                }
                else
                {
                    this.txtNamespace.Text = ns;
                }
            }
        }
예제 #4
0
        public void UnavailableEnvironments()
        {
            var collection = new Microsoft.Build.Evaluation.ProjectCollection();

            try {
                var service = new MockInterpreterOptionsService();
                var proj    = collection.LoadProject(TestData.GetPath(@"TestData\Environments\Unavailable.pyproj"));

                using (var provider = new MSBuildProjectInterpreterFactoryProvider(service, proj)) {
                    try {
                        provider.DiscoverInterpreters();
                        Assert.Fail("Expected InvalidDataException in DiscoverInterpreters");
                    } catch (InvalidDataException ex) {
                        AssertUtil.AreEqual(ex.Message
                                            .Replace(TestData.GetPath("TestData\\Environments\\"), "$")
                                            .Split('\r', '\n')
                                            .Where(s => !string.IsNullOrEmpty(s))
                                            .Select(s => s.Trim()),
                                            "Some project interpreters failed to load:",
                                            @"Interpreter $env\ has invalid value for 'Id': INVALID ID",
                                            @"Interpreter $env\ has invalid value for 'Version': INVALID VERSION",
                                            @"Base interpreter $env\ has invalid value for 'BaseInterpreter': INVALID BASE",
                                            @"Interpreter $env\ has invalid value for 'InterpreterPath': INVALID<>PATH",
                                            @"Interpreter $env\ has invalid value for 'WindowsInterpreterPath': INVALID<>PATH",
                                            @"Interpreter $env\ has invalid value for 'LibraryPath': INVALID<>PATH",
                                            @"Base interpreter $env\ has invalid value for 'BaseInterpreter': {98512745-4ac7-4abb-9f33-120af32edc77}"
                                            );
                    }

                    var factories = provider.GetInterpreterFactories().ToList();
                    foreach (var fact in factories)
                    {
                        Console.WriteLine("{0}: {1}", fact.GetType().FullName, fact.Description);
                    }

                    foreach (var fact in factories)
                    {
                        Assert.IsInstanceOfType(
                            fact,
                            typeof(MSBuildProjectInterpreterFactoryProvider.NotFoundInterpreterFactory),
                            string.Format("{0} was not correct type", fact.Description)
                            );
                        Assert.IsFalse(provider.IsAvailable(fact), string.Format("{0} was not unavailable", fact.Description));
                    }

                    AssertUtil.AreEqual(factories.Select(f => f.Description),
                                        "Invalid BaseInterpreter (unavailable)",
                                        "Invalid InterpreterPath (unavailable)",
                                        "Invalid WindowsInterpreterPath (unavailable)",
                                        "Invalid LibraryPath (unavailable)",
                                        "Absent BaseInterpreter (unavailable)",
                                        "Unknown Python 2.7"
                                        );
                }
            } finally {
                collection.UnloadAllProjects();
                collection.Dispose();
            }
        }
예제 #5
0
        public void UnavailableEnvironments()
        {
            var collection = new Microsoft.Build.Evaluation.ProjectCollection();

            try {
                var service         = new MockInterpreterOptionsService();
                var proj            = collection.LoadProject(TestData.GetPath(@"TestData\Environments\Unavailable.pyproj"));
                var contextProvider = new MockProjectContextProvider(proj);

                var logger = new MockLogger();

                using (var provider = new MSBuildProjectInterpreterFactoryProvider(
                           new[] { new Lazy <IProjectContextProvider>(() => contextProvider) },
                           null,
                           new[] { new Lazy <IInterpreterLog>(() => logger) })) {
                    var configs = provider.GetInterpreterConfigurations().ToArray();
                    // force the load...
                    AssertUtil.AreEqual(
                        logger.Errors.ToString()
                        .Replace(TestData.GetPath("TestData\\Environments\\"), "$")
                        .Split('\r', '\n')
                        .Where(s => !string.IsNullOrEmpty(s))
                        .Select(s => s.Trim()),
                        @"Interpreter $env\ has invalid value for 'Id':",
                        @"Interpreter $env\ has invalid value for 'Version': INVALID VERSION",
                        @"Interpreter $env\ has invalid value for 'InterpreterPath': INVALID<>PATH",
                        @"Interpreter $env\ has invalid value for 'WindowsInterpreterPath': INVALID<>PATH"
                        );

                    var factories = provider.GetInterpreterFactories().ToList();
                    foreach (var fact in factories)
                    {
                        Console.WriteLine("{0}: {1}", fact.GetType().FullName, fact.Configuration.Description);
                    }

                    foreach (var fact in factories)
                    {
                        Assert.IsInstanceOfType(
                            fact,
                            typeof(NotFoundInterpreterFactory),
                            string.Format("{0} was not correct type", fact.Configuration.Description)
                            );
                        Assert.IsFalse(fact.Configuration.IsAvailable(), string.Format("{0} was not unavailable", fact.Configuration.Description));
                    }

                    AssertUtil.AreEqual(factories.Select(f => f.Configuration.Description),
                                        "Invalid InterpreterPath (unavailable)",
                                        "Invalid WindowsInterpreterPath (unavailable)"
                                        );
                }
            } finally {
                collection.UnloadAllProjects();
                collection.Dispose();
            }
        }
예제 #6
0
        private MSB.Evaluation.Project EvaluateProjectFileCore(string filePath, IReadOnlyDictionary <string, string> projectConfigurationsInSolution = null)
        {
            var localProperties = new Dictionary <string, string>(_globalProperties);

            if (projectConfigurationsInSolution != null &&
                localProperties.TryGetValue(PropertyNames.Configuration, out string solutionConfiguration))
            {
                if (!localProperties.TryGetValue(PropertyNames.Platform, out string solutionPlatform))
                {
                    solutionPlatform = "Any CPU";
                }

                var solutionSelector = $"{solutionConfiguration}|{solutionPlatform}.ActiveCfg";
                _logger.LogDebug($"Found configuration `{solutionSelector}` in solution for '{filePath}'.");

                if (projectConfigurationsInSolution.TryGetValue(solutionSelector, out string projectSelector))
                {
                    var splitted = projectSelector.Split('|');
                    if (splitted.Length == 2)
                    {
                        var projectConfiguration = splitted[0];
                        localProperties[PropertyNames.Configuration] = projectConfiguration;
                        // NOTE: Solution often defines configuration as `Any CPU` whereas project relies on `AnyCPU`
                        var projectPlatform = splitted[1].Replace("Any CPU", "AnyCPU");
                        localProperties[PropertyNames.Platform] = projectPlatform;
                        _logger.LogDebug($"Using configuration from solution: `{projectConfiguration}|{projectPlatform}`");
                    }
                }
            }

            // Evaluate the MSBuild project
            var projectCollection = new MSB.Evaluation.ProjectCollection(localProperties);

            var toolsVersion = _options.ToolsVersion;

            if (string.IsNullOrEmpty(toolsVersion) || Version.TryParse(toolsVersion, out _))
            {
                toolsVersion = projectCollection.DefaultToolsVersion;
            }

            toolsVersion = GetLegalToolsetVersion(toolsVersion, projectCollection.Toolsets);

            var project = projectCollection.LoadProject(filePath, toolsVersion);

            SetTargetFrameworkIfNeeded(project);

            return(project);
        }
예제 #7
0
        private MSB.Evaluation.Project EvaluateProjectFileCore(string filePath)
        {
            // Evaluate the MSBuild project
            var projectCollection = new MSB.Evaluation.ProjectCollection(_globalProperties);

            var toolsVersion = _options.ToolsVersion;

            if (string.IsNullOrEmpty(toolsVersion) || Version.TryParse(toolsVersion, out _))
            {
                toolsVersion = projectCollection.DefaultToolsVersion;
            }

            toolsVersion = GetLegalToolsetVersion(toolsVersion, projectCollection.Toolsets);

            return(projectCollection.LoadProject(filePath, toolsVersion));
        }
예제 #8
0
        private static void addReference(string projectFile, string filename)
        {
            using (var collection = new Microsoft.Build.Evaluation.ProjectCollection())
            {
                collection.LoadProject(projectFile);
                var project = collection.LoadedProjects.FirstOrDefault(o => o.FullPath == projectFile);
                var items   = project.GetItems("Compile");
                if (!items.Any(o => o.EvaluatedInclude == filename || o.UnevaluatedInclude == filename))
                {
                    project.AddItem("Compile", filename);
                    project.Save();
                }

                collection.UnloadProject(project);
            }
        }
        static bool TryLoadProjectFromCsproj(string csprojFullPath, out Microsoft.Build.Evaluation.Project project, out string projectName, out Context.ProjectType projectType, out Context.ProjectOutputType projectOutputType)
        {
            try
            {
                Microsoft.Build.Evaluation.ProjectCollection collection = new Microsoft.Build.Evaluation.ProjectCollection();
                collection.DefaultToolsVersion = "4.0";
                Microsoft.Build.Evaluation.Project theProject = collection.LoadProject(csprojFullPath);
                string projectTypeGuids = theProject.GetPropertyValue("ProjectTypeGuids"); //cf. https://github.com/Microsoft/visualfsharp/blob/master/vsintegration/src/FSharp.ProjectSystem.Base/Project/ProjectFactory.cs
                string isSilverlightApplicationString = theProject.GetPropertyValue("SilverlightApplication");

                // Get the project name:
                projectName = System.IO.Path.GetFileNameWithoutExtension(csprojFullPath);

                // Get the Project Type:
                projectType = GetProjectType(projectTypeGuids);

                // Get the project Output Type:
                Func <string, string> functionToGetAProjectProperty = (string propertyName) =>
                {
                    return(theProject.GetPropertyValue(propertyName));
                };
                projectOutputType = GetProjectOutputType(projectType, functionToGetAProjectProperty, functionToGetAProjectProperty);

                // Return the project itself as well:
                project = theProject;

                return(true);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                project           = null;
                projectName       = null;
                projectType       = Context.ProjectType.Other;
                projectOutputType = Context.ProjectOutputType.Unknown;
                return(false);
            }
        }
예제 #10
0
        public void UnavailableEnvironments() {
            var collection = new Microsoft.Build.Evaluation.ProjectCollection();
            try {
                var service = new MockInterpreterOptionsService();
                var proj = collection.LoadProject(TestData.GetPath(@"TestData\Environments\Unavailable.pyproj"));

                using (var provider = new MSBuildProjectInterpreterFactoryProvider(service, proj)) {
                    try {
                        provider.DiscoverInterpreters();
                        Assert.Fail("Expected InvalidDataException in DiscoverInterpreters");
                    } catch (InvalidDataException ex) {
                        AssertUtil.AreEqual(ex.Message
                            .Replace(TestData.GetPath("TestData\\Environments\\"), "$")
                            .Split('\r', '\n')
                            .Where(s => !string.IsNullOrEmpty(s))
                            .Select(s => s.Trim()),
                            "Some project interpreters failed to load:",
                            @"Interpreter $env\ has invalid value for 'Id': INVALID ID",
                            @"Interpreter $env\ has invalid value for 'Version': INVALID VERSION",
                            @"Interpreter $env\ has invalid value for 'BaseInterpreter': INVALID BASE",
                            @"Interpreter $env\ has invalid value for 'InterpreterPath': INVALID<>PATH",
                            @"Interpreter $env\ has invalid value for 'WindowsInterpreterPath': INVALID<>PATH",
                            @"Interpreter $env\ has invalid value for 'LibraryPath': INVALID<>PATH",
                            @"Interpreter $env\ has invalid value for 'BaseInterpreter': {98512745-4ac7-4abb-9f33-120af32edc77}"
                        );
                    }

                    var factories = provider.GetInterpreterFactories().ToList();
                    foreach (var fact in factories) {
                        Console.WriteLine("{0}: {1}", fact.GetType().FullName, fact.Description);
                    }

                    foreach (var fact in factories) {
                        Assert.IsInstanceOfType(
                            fact,
                            typeof(MSBuildProjectInterpreterFactoryProvider.NotFoundInterpreterFactory),
                            string.Format("{0} was not correct type", fact.Description)
                        );
                        Assert.IsFalse(provider.IsAvailable(fact), string.Format("{0} was not unavailable", fact.Description));
                    }

                    AssertUtil.AreEqual(factories.Select(f => f.Description),
                        "Invalid BaseInterpreter (unavailable)",
                        "Invalid InterpreterPath (unavailable)",
                        "Invalid WindowsInterpreterPath (unavailable)",
                        "Invalid LibraryPath (unavailable)",
                        "Absent BaseInterpreter (unavailable)",
                        "Unknown Python 2.7"
                    );
                }
            } finally {
                collection.UnloadAllProjects();
                collection.Dispose();
            }
        }
예제 #11
0
        public void UnavailableEnvironments() {
            var collection = new Microsoft.Build.Evaluation.ProjectCollection();
            try {
                var service = new MockInterpreterOptionsService();
                var proj = collection.LoadProject(TestData.GetPath(@"TestData\Environments\Unavailable.pyproj"));
                var contextProvider = new MockProjectContextProvider(proj);

                var logger = new MockLogger();

                using (var provider = new MSBuildProjectInterpreterFactoryProvider(
                    new[] { new Lazy<IProjectContextProvider>(() => contextProvider) },
                    null,
                    new[] { new Lazy<IInterpreterLog>(() => logger) })) {
                    var configs = provider.GetInterpreterConfigurations().ToArray();
                    // force the load...
                    AssertUtil.AreEqual(
                        logger.Errors.ToString()
                        .Replace(TestData.GetPath("TestData\\Environments\\"), "$")
                        .Split('\r', '\n')
                        .Where(s => !string.IsNullOrEmpty(s))
                        .Select(s => s.Trim()),
                        @"Interpreter $env\ has invalid value for 'Id':",
                        @"Interpreter $env\ has invalid value for 'Version': INVALID VERSION",
                        @"Interpreter $env\ has invalid value for 'InterpreterPath': INVALID<>PATH",
                        @"Interpreter $env\ has invalid value for 'WindowsInterpreterPath': INVALID<>PATH"
                    );

                    var factories = provider.GetInterpreterFactories().ToList();
                    foreach (var fact in factories) {
                        Console.WriteLine("{0}: {1}", fact.GetType().FullName, fact.Configuration.Description);
                    }

                    foreach (var fact in factories) {
                        Assert.IsInstanceOfType(
                            fact,
                            typeof(NotFoundInterpreterFactory),
                            string.Format("{0} was not correct type", fact.Configuration.Description)
                        );
                        Assert.IsFalse(fact.Configuration.IsAvailable(), string.Format("{0} was not unavailable", fact.Configuration.Description));
                    }

                    AssertUtil.AreEqual(factories.Select(f => f.Configuration.Description),
                        "Invalid InterpreterPath (unavailable)",
                        "Invalid WindowsInterpreterPath (unavailable)"
                    );
                }
            } finally {
                collection.UnloadAllProjects();
                collection.Dispose();
            }
        }
예제 #12
0
        public async Task <Dictionary <string, string> > EvaluateProjectPropertiesAsync(string projectPath, string targetFramework, IEnumerable <string> propertyNames, IDictionary <string, string> globalProperties, ILogger logger, CancellationToken cancellationToken)
        {
            var propertyTable = new Dictionary <string, string>();

            using (var safeLogger = await SafeLogger.WriteStartOperationAsync(logger, $"Resolving {propertyNames.Count()} project properties ...").ConfigureAwait(false))
            {
                ValidatePropertyNames(propertyNames);
                ValidatePropertyNames(globalProperties);

                var workingDirectory = Path.GetDirectoryName(projectPath);
                var sdkVersion       = await GetSdkVersionAsync(workingDirectory, logger, cancellationToken).ConfigureAwait(false);

                var sdkPath = await GetSdkPathAsync(workingDirectory, logger, cancellationToken).ConfigureAwait(false);

                try
                {
#if NETCORE
                    var propertiesResolved = false;

                    try
                    {
                        // In order for the MSBuild project evaluation API to work in .NET Core, the code must be executed directly from the .NET Core SDK assemblies.
                        // MSBuild libraries need to be explicitly loaded from the right SDK path (the one that corresponds to the runtime executing the project) as
                        // dependencies must be loaded from the executing runtime. This is not always possible, a newer SDK can load an older runtime; also, msbuild
                        // scripts from a newer SDK may not be supported by an older SDKs.
                        // Consider: A project created with the command 'dotnet new console' will target the right platform for the current SDK.

                        Assembly msbuildAssembly = await LoadMSBuildAssembliesAsync(sdkPath, logger, cancellationToken).ConfigureAwait(false);

                        if (msbuildAssembly != null)
                        {
                            var projType         = msbuildAssembly.GetType("Microsoft.Build.Evaluation.Project", true, false);
                            var projInstance     = Activator.CreateInstance(projType, new object[] { projectPath, globalProperties, /*toolsVersion*/ null });
                            var getPropertyValue = projType.GetMethod("GetPropertyValue");

                            if (getPropertyValue != null)
                            {
                                foreach (var propertyName in propertyNames)
                                {
                                    var propertyValue = getPropertyValue.Invoke(projInstance, new object[] { propertyName }).ToString();
                                    propertyTable[propertyName] = propertyValue;
                                    await safeLogger.WriteMessageAsync($"Evaluated '{propertyName}={propertyValue}'", logToUI : false).ConfigureAwait(false);
                                }
                                propertiesResolved = true;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        await safeLogger.WriteMessageAsync(ex.Message, logToUI : false).ConfigureAwait(false);
                    }

                    if (!propertiesResolved)
                    {
                        foreach (var propertyName in propertyNames)
                        {
                            var propertyValue = GetDefaultPropertyValue(projectPath, targetFramework, propertyName);
                            propertyTable[propertyName] = propertyValue;
                            await safeLogger.WriteMessageAsync($"Resolved '{propertyName}={propertyValue}'", logToUI : false).ConfigureAwait(false);
                        }
                    }
#else
                    // don't use GlobalProjectCollection as once a project is loaded into memory changes to the project file won't take effect until the solution is reloaded.
                    var projCollection = new Microsoft.Build.Evaluation.ProjectCollection(globalProperties);
                    var project        = projCollection.LoadProject(projectPath);

                    foreach (var propertyName in propertyNames)
                    {
                        var propertyValue = project.GetPropertyValue(propertyName);
                        propertyTable[propertyName] = propertyValue;
                        await safeLogger.WriteMessageAsync($"Evaluated '{propertyName}={propertyValue}'", logToUI : false).ConfigureAwait(false);
                    }
#endif // NETCORE
                }
                catch (Exception ex)
                {
                    if (Utils.IsFatalOrUnexpected(ex))
                    {
                        throw;
                    }
                    await safeLogger.WriteErrorAsync($"{ex.Message}{Environment.NewLine}{ex.StackTrace}", logToUI : false);
                }
                finally
                {
                    // Ensure the dictionary is populated in any case, the client needs to validate the values but not the collection.
                    foreach (var propertyName in propertyNames)
                    {
                        if (!propertyTable.ContainsKey(propertyName))
                        {
                            propertyTable[propertyName] = string.Empty;
                        }
                    }
                }
            }

            return(propertyTable);
        }