public async Task <ImmutableArray <ProjectFileInfo> > GetProjectFileInfosAsync(CancellationToken cancellationToken) { var targetFrameworkValue = _loadedProject.GetPropertyValue(PropertyNames.TargetFramework); var targetFrameworksValue = _loadedProject.GetPropertyValue(PropertyNames.TargetFrameworks); if (string.IsNullOrEmpty(targetFrameworkValue) && !string.IsNullOrEmpty(targetFrameworksValue)) { // This project has a <TargetFrameworks> property, but does not specify a <TargetFramework>. // In this case, we need to iterate through the <TargetFrameworks>, set <TargetFramework> with // each value, and build the project. var hasTargetFrameworkProp = _loadedProject.GetProperty(PropertyNames.TargetFramework) != null; var targetFrameworks = targetFrameworksValue.Split(';'); var results = ImmutableArray.CreateBuilder <ProjectFileInfo>(targetFrameworks.Length); foreach (var targetFramework in targetFrameworks) { _loadedProject.SetProperty(PropertyNames.TargetFramework, targetFramework); _loadedProject.ReevaluateIfNecessary(); var projectFileInfo = await BuildProjectFileInfoAsync(cancellationToken).ConfigureAwait(false); results.Add(projectFileInfo); } // Remove the <TargetFramework> property if it didn't exist in the file before we set it. // Otherwise, set it back to it's original value. if (!hasTargetFrameworkProp) { var targetFrameworkProp = _loadedProject.GetProperty(PropertyNames.TargetFramework); _loadedProject.RemoveProperty(targetFrameworkProp); } else { _loadedProject.SetProperty(PropertyNames.TargetFramework, targetFrameworkValue); } _loadedProject.ReevaluateIfNecessary(); return(results.ToImmutable()); } else { var projectFileInfo = await BuildProjectFileInfoAsync(cancellationToken).ConfigureAwait(false); return(ImmutableArray.Create(projectFileInfo)); } }
protected override byte[] GenerateCode(string inputFileName, string inputFileContent) { // Get active project // TODO: Instead of a custom code generator, we should have a context command or something like that. // This should also allow generation of multiple files var lines = Regex.Split(inputFileContent, "\r\n|\r|\n"); if (lines.Length == 0 || lines[0].Length == 0) { throw new InvalidOperationException("Source should contain project filename."); } var projectFullName = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(inputFileName), lines[0])); if (!File.Exists(projectFullName)) { throw new InvalidOperationException("Project file doesn't exist."); } string assemblyOutput, intermediateAssembly; // Get Evaluation Project Microsoft.Build.Evaluation.Project msbuildProject = Microsoft.Build.Evaluation.ProjectCollection.GlobalProjectCollection.GetLoadedProjects(projectFullName).First(); // Set ParadoxBuildStep variable and change IntermediateOutputPath var property1 = msbuildProject.SetProperty("ParadoxBuildStep", "StepData"); var property2 = msbuildProject.SetProperty("IntermediateOutputPath", @"obj\StepData\"); // Reevaluate dependent properties msbuildProject.ReevaluateIfNecessary(); try { var outputPane = GetOutputPane(); // Create logger var buildLogger = new IDEBuildLogger(outputPane, new TaskProvider(GlobalServiceProvider), VsHelper.GetCurrentHierarchy(GlobalServiceProvider)); buildLogger.Verbosity = Microsoft.Build.Framework.LoggerVerbosity.Diagnostic; var evaluatedProperties = new Dictionary <string, Microsoft.Build.Evaluation.ProjectProperty>(); foreach (var evaluatedProperty in msbuildProject.AllEvaluatedProperties) { evaluatedProperties[evaluatedProperty.Name] = evaluatedProperty; } // Output properties foreach (var evaluatedProperty in evaluatedProperties) { outputPane.OutputStringThreadSafe(string.Format( "$({0}) = {1} was evaluated as {2}\n", evaluatedProperty.Key, evaluatedProperty.Value.UnevaluatedValue, evaluatedProperty.Value.EvaluatedValue)); } // Compile project (only intermediate assembly) // Dependencies will be built as well //var manager = BuildManager.DefaultBuildManager; using (var manager = new BuildManager()) { var pc = new Microsoft.Build.Evaluation.ProjectCollection(); var globalProperties = new Dictionary <string, string>(); globalProperties["SolutionName"] = evaluatedProperties["SolutionName"].EvaluatedValue; globalProperties["SolutionDir"] = evaluatedProperties["SolutionDir"].EvaluatedValue; var projectInstance = new ProjectInstance(projectFullName, globalProperties, null); var buildResult = manager.Build( new BuildParameters(pc) { Loggers = new[] { buildLogger }, DetailedSummary = true, }, new BuildRequestData(projectInstance, new[] { "Compile" }, null)); if (buildResult.OverallResult == BuildResultCode.Failure) { throw new InvalidOperationException(string.Format("Build of {0} failed.", projectFullName)); } } // Get TargetPath and IntermediateAssembly assemblyOutput = msbuildProject.AllEvaluatedProperties.Last(x => x.Name == "TargetPath").EvaluatedValue; intermediateAssembly = msbuildProject.AllEvaluatedItems.First(x => x.ItemType == "IntermediateAssembly").EvaluatedInclude; } finally { msbuildProject.RemoveProperty(property1); msbuildProject.RemoveProperty(property2); } // Defer execution to current Paradox VS package plugin try { var remoteCommands = ParadoxCommandsProxy.GetProxy(); return(remoteCommands.GenerateDataClasses(assemblyOutput, projectFullName, intermediateAssembly)); } catch (Exception ex) { GeneratorError(4, ex.ToString(), 0, 0); return(new byte[0]); } }