// Ignore: Changes to the current directory interfere with the toolset reader. public void SolutionDoesntPassSubToolsetToChildProjects() { try { string classLibraryContents = @" <Project ToolsVersion=""4.0"" DefaultTargets=""Build"" xmlns='http://schemas.microsoft.com/developer/msbuild/2003'> <Target Name='Build'> <Message Text='.[$(VisualStudioVersion)].' /> <Message Text='.[[$(MSBuildToolsVersion)]].' /> </Target> </Project> "; string projectFile = ObjectModelHelpers.CreateFileInTempProjectDirectory("ClassLibrary1.csproj", classLibraryContents); string solutionFileContents = @" Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Dev11 Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ClassLibrary1"", ""ClassLibrary1.csproj"", ""{6185CC21-BE89-448A-B3C0-D1C27112E595}"" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Mixed Platforms = Debug|Mixed Platforms Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Mixed Platforms.ActiveCfg = CSConfig1|Any CPU {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Mixed Platforms.Build.0 = CSConfig1|Any CPU {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.ActiveCfg = CSConfig2|Any CPU EndGlobalSection EndGlobal "; string solutionFile = ObjectModelHelpers.CreateFileInTempProjectDirectory("Foo.sln", solutionFileContents); SolutionFile sp = new SolutionFile(); sp.FullPath = solutionFile; sp.ParseSolutionFile(); ProjectInstance[] instances = SolutionProjectGenerator.Generate(sp, null, null, new BuildEventContext(0, 0, 0, 0), null); Assert.AreEqual(ObjectModelHelpers.MSBuildDefaultToolsVersion, instances[0].ToolsVersion); Assert.AreEqual("11.0", instances[0].SubToolsetVersion); Assert.AreEqual("11.0", instances[0].GetPropertyValue("VisualStudioVersion")); MockLogger logger = new MockLogger(); List<ILogger> loggers = new List<ILogger>(1); loggers.Add(logger); instances[0].Build(loggers); logger.AssertLogContains(String.Format(".[{0}].", ObjectModelHelpers.MSBuildDefaultToolsVersion)); } finally { ObjectModelHelpers.DeleteTempProjectDirectory(); } }
public void SolutionConfigurationWithDependenciesRelaysItsOutputs() { #region Large strings representing solution & projects const string solutionFileContents = @" Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 11 Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `B`, `B.csproj`, `{881C1674-4ECA-451D-85B6-D7C59B7F16FA}` ProjectSection(ProjectDependencies) = postProject {4A727FF8-65F2-401E-95AD-7C8BBFBE3167} = {4A727FF8-65F2-401E-95AD-7C8BBFBE3167} EndProjectSection EndProject Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `C`, `C.csproj`, `{4A727FF8-65F2-401E-95AD-7C8BBFBE3167}` EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = preSolution {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|Any CPU.Build.0 = Debug|Any CPU {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Release|Any CPU.ActiveCfg = Release|Any CPU {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Release|Any CPU.Build.0 = Release|Any CPU {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.Build.0 = Debug|Any CPU {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|Any CPU.ActiveCfg = Release|Any CPU {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal "; const string projectBravoFileContents = @" <Project ToolsVersion='msbuilddefaulttoolsversion' DefaultTargets='Build' xmlns='msbuildnamespace'> <Target Name='Build' Outputs='@(ComputedQuestion)'> <ItemGroup> <ComputedQuestion Include='What do you get if you multiply six by nine' /> </ItemGroup> </Target> </Project> "; const string projectCharlieFileContents = @" <Project ToolsVersion='msbuilddefaulttoolsversion' DefaultTargets='Build' xmlns='msbuildnamespace'> <Target Name='Build' Outputs='@(ComputedAnswer)'> <ItemGroup> <ComputedAnswer Include='42' /> </ItemGroup> </Target> </Project> "; const string automaticProjectFileContents = @" <Project ToolsVersion='msbuilddefaulttoolsversion' DefaultTargets='compile' xmlns='msbuildnamespace'> <Target Name='compile'> <MSBuild Projects='B.csproj' Targets='Build'> <Output TaskParameter='TargetOutputs' ItemName='BravoProjectOutputs' /> </MSBuild> <Message Importance='high' Text='BravoProjectOutputs: @(BravoProjectOutputs)' /> <MSBuild Projects='C.csproj' Targets='Build'> <Output TaskParameter='TargetOutputs' ItemName='CharlieProjectOutputs' /> </MSBuild> <Message Importance='high' Text='CharlieProjectOutputs: @(CharlieProjectOutputs)' /> <MSBuild Projects='B.csproj.metaproj' Targets='Build'> <Output TaskParameter='TargetOutputs' ItemName='BravoMetaProjectOutputs' /> </MSBuild> <Message Importance='high' Text='BravoMetaProjectOutputs: @(BravoMetaProjectOutputs)' /> <Error Condition=` '@(CharlieProjectOutputs);@(BravoProjectOutputs)' != '@(BravoMetaProjectOutputs)' ` Text='Metaproj must relay outputs' /> </Target> </Project>"; #endregion // arrange var logger = new MockLogger(); var loggers = new List<ILogger>(1) {logger}; var solutionFile = ObjectModelHelpers.CreateFileInTempProjectDirectory("MSBuildIssue.sln", solutionFileContents); ObjectModelHelpers.CreateFileInTempProjectDirectory("B.csproj", projectBravoFileContents); ObjectModelHelpers.CreateFileInTempProjectDirectory("C.csproj", projectCharlieFileContents); var solution = new SolutionFile {FullPath = solutionFile}; solution.ParseSolutionFile(); // act var instances = SolutionProjectGenerator.Generate(solution, null, null, new BuildEventContext(0, 0, 0, 0), null); // assert var projectBravoMetaProject = instances[1]; Assert.IsFalse(projectBravoMetaProject.Targets.Any(kvp => kvp.Value.Outputs.Equals("@()")), "The outputItem parameter can be null; the Target element should not have an Outputs attribute in that case."); // saves the in-memory metaproj to disk projectBravoMetaProject.ToProjectRootElement().Save(projectBravoMetaProject.FullPath); var automaticProjectFile = ObjectModelHelpers.CreateFileInTempProjectDirectory("automatic.msbuild", automaticProjectFileContents); var automaticProject = new Project(automaticProjectFile); var buildResult = automaticProject.Build(loggers); Assert.AreEqual(true, buildResult, String.Join(Environment.NewLine, logger.Errors.Select(beea => beea.Message))); }
// Ignore: Changes to the current directory interfere with the toolset reader. public void SolutionPassesSubToolsetToChildProjects2() { string classLibraryContentsToolsV4 = ObjectModelHelpers.CleanupFileContents( @" <Project ToolsVersion=""4.0"" DefaultTargets=""Build"" xmlns='msbuildnamespace'> <Target Name='Build'> <Message Text='.[$(VisualStudioVersion)]. .[$(MSBuildToolsVersion)].' /> </Target> </Project> "); string classLibraryContentsToolsV12 = ObjectModelHelpers.CleanupFileContents( @" <Project ToolsVersion=""msbuilddefaulttoolsversion"" DefaultTargets=""Build"" xmlns='msbuildnamespace'> <Target Name='Build'> <Message Text='.[$(VisualStudioVersion)]. .[$(MSBuildToolsVersion)].' /> </Target> </Project> "); string solutionFilePreambleV11 = @" Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Dev11 "; string solutionFilePreambleV12 = @" Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Dev11 VisualStudioVersion = 12.0.20311.0 VSPRO_PLATFORM MinimumVisualStudioVersion = 10.0.40219.1 "; string solutionBodySingleProjectContents = @" Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ClassLibrary1"", ""ClassLibrary1.csproj"", ""{6185CC21-BE89-448A-B3C0-D1C27112E595}"" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Mixed Platforms = Debug|Mixed Platforms Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Mixed Platforms.ActiveCfg = CSConfig1|Any CPU {6185CC21-BE89-448A-B3C0-D1C27112E595}.Debug|Mixed Platforms.Build.0 = CSConfig1|Any CPU {6185CC21-BE89-448A-B3C0-D1C27112E595}.Release|Any CPU.ActiveCfg = CSConfig2|Any CPU EndGlobalSection EndGlobal "; string solutionBodyMultipleProjectsContents = @" Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ClassLibrary1"", ""ClassLibrary1.csproj"", ""{A437DBE9-DCAA-46D8-9D80-A50EDB2244FD}"" EndProject Project(""{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"") = ""ClassLibrary2"", ""ClassLibrary2.csproj"", ""{84AA5584-4B0F-41DE-95AA-589E1447EDA0}"" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {A437DBE9-DCAA-46D8-9D80-A50EDB2244FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A437DBE9-DCAA-46D8-9D80-A50EDB2244FD}.Debug|Any CPU.Build.0 = Debug|Any CPU {A437DBE9-DCAA-46D8-9D80-A50EDB2244FD}.Release|Any CPU.ActiveCfg = Release|Any CPU {A437DBE9-DCAA-46D8-9D80-A50EDB2244FD}.Release|Any CPU.Build.0 = Release|Any CPU {84AA5584-4B0F-41DE-95AA-589E1447EDA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {84AA5584-4B0F-41DE-95AA-589E1447EDA0}.Debug|Any CPU.Build.0 = Debug|Any CPU {84AA5584-4B0F-41DE-95AA-589E1447EDA0}.Release|Any CPU.ActiveCfg = Release|Any CPU {84AA5584-4B0F-41DE-95AA-589E1447EDA0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal "; string solutionFileContentsDev11 = solutionFilePreambleV11 + solutionBodySingleProjectContents; string solutionFileContentsDev12 = solutionFilePreambleV12 + solutionBodySingleProjectContents; string[] solutions = { solutionFileContentsDev11, solutionFileContentsDev12, solutionFileContentsDev12 }; string[] projects = { classLibraryContentsToolsV4, classLibraryContentsToolsV4, classLibraryContentsToolsV12 }; string[] logoutputs = { ".[11.0]. .[4.0].", ".[11.0]. .[4.0].", String.Format(".[{0}]. .[{0}].", ObjectModelHelpers.MSBuildDefaultToolsVersion) }; string previousLegacyEnvironmentVariable = Environment.GetEnvironmentVariable("MSBUILDLEGACYDEFAULTTOOLSVERSION"); try { Environment.SetEnvironmentVariable("MSBUILDLEGACYDEFAULTTOOLSVERSION", "1"); InternalUtilities.RefreshInternalEnvironmentValues(); for (int i = 0; i < solutions.Length; i++) { string solutionFile = ObjectModelHelpers.CreateFileInTempProjectDirectory("Foo.sln", solutions[i]); string projectFile = ObjectModelHelpers.CreateFileInTempProjectDirectory("ClassLibrary1.csproj", projects[i]); SolutionFile sp = new SolutionFile(); sp.FullPath = solutionFile; sp.ParseSolutionFile(); ProjectInstance[] instances = SolutionProjectGenerator.Generate(sp, null, null, new BuildEventContext(0, 0, 0, 0), null); MockLogger logger = new MockLogger(); List<ILogger> loggers = new List<ILogger>(1); loggers.Add(logger); instances[0].Build(loggers); logger.AssertLogContains(logoutputs[i]); } // Test Dev 12 sln and mixed v4.0 and v12.0 projects string solutionFileContentsDev12MultipleProjects = solutionFilePreambleV12 + solutionBodyMultipleProjectsContents; string solutionFileMultipleProjects = ObjectModelHelpers.CreateFileInTempProjectDirectory("Foo.sln", solutionFileContentsDev12MultipleProjects); string projectFileV4 = ObjectModelHelpers.CreateFileInTempProjectDirectory("ClassLibrary1.csproj", classLibraryContentsToolsV4); string projectFileV12 = ObjectModelHelpers.CreateFileInTempProjectDirectory("ClassLibrary2.csproj", classLibraryContentsToolsV12); SolutionFile sp1 = new SolutionFile(); sp1.FullPath = solutionFileMultipleProjects; sp1.ParseSolutionFile(); ProjectInstance[] instances1 = SolutionProjectGenerator.Generate(sp1, null, null, new BuildEventContext(0, 0, 0, 0), null); MockLogger logger1 = new MockLogger(); List<ILogger> loggers1 = new List<ILogger>(1); loggers1.Add(logger1); instances1[0].Build(loggers1); logger1.AssertLogContains(".[11.0]. .[4.0]."); logger1.AssertLogContains(String.Format(".[{0}]. .[{0}].", ObjectModelHelpers.MSBuildDefaultToolsVersion)); } finally { Environment.SetEnvironmentVariable("MSBUILDLEGACYDEFAULTTOOLSVERSION", previousLegacyEnvironmentVariable); InternalUtilities.RefreshInternalEnvironmentValues(); } }
/// <summary> /// Convert passed in solution file to an MSBuild project. This method is used by Sln2Proj /// </summary> public bool ConvertSLN2Proj(string nameSolutionFile) { // Set the environment variable to cause the SolutionProjectGenerator to emit the project to disk string oldValueForMSBuildEmitSolution = Environment.GetEnvironmentVariable("MSBuildEmitSolution"); Environment.SetEnvironmentVariable("MSBuildEmitSolution", "1"); if (nameSolutionFile == null || !File.Exists(nameSolutionFile)) { return false; } // Parse the solution SolutionFile solution = new SolutionFile(); solution.FullPath = nameSolutionFile; solution.ParseSolutionFile(); // Generate the in-memory MSBuild project and output it to disk ProjectInstance[] instance = SolutionProjectGenerator.Generate(solution, null, null, BuildEventContext.Invalid, null); //Reset the environment variable Environment.SetEnvironmentVariable("MSBuildEmitSolution", oldValueForMSBuildEmitSolution); return true; }
/// <summary> /// This method takes a path to a solution file, parses the projects and project dependencies /// in the solution file, and creates internal data structures representing the projects within /// the SLN. /// </summary> public static SolutionFile Parse(string solutionFile) { SolutionFile parser = new SolutionFile(); parser.FullPath = solutionFile; parser.ParseSolutionFile(); return parser; }
public void SolutionConfigurationWithDependenciesRelaysItsOutputs() { #region Large strings representing solution & projects const string solutionFileContents = @" Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 11 Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `B`, `B.csproj`, `{881C1674-4ECA-451D-85B6-D7C59B7F16FA}` ProjectSection(ProjectDependencies) = postProject {4A727FF8-65F2-401E-95AD-7C8BBFBE3167} = {4A727FF8-65F2-401E-95AD-7C8BBFBE3167} EndProjectSection EndProject Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `C`, `C.csproj`, `{4A727FF8-65F2-401E-95AD-7C8BBFBE3167}` EndProject Project(`{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}`) = `D`, `D.csproj`, `{B6E7E06F-FC0B-48F1-911A-55E0E1566F00}` EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = preSolution {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {4A727FF8-65F2-401E-95AD-7C8BBFBE3167}.Debug|Any CPU.Build.0 = Debug|Any CPU {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {881C1674-4ECA-451D-85B6-D7C59B7F16FA}.Debug|Any CPU.Build.0 = Debug|Any CPU {B6E7E06F-FC0B-48F1-911A-55E0E1566F00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B6E7E06F-FC0B-48F1-911A-55E0E1566F00}.Debug|Any CPU.Build.0 = Debug|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal "; const string projectBravoFileContents = @" <Project ToolsVersion='msbuilddefaulttoolsversion' DefaultTargets='Build' xmlns='msbuildnamespace'> <Target Name='Build' Outputs='@(ComputedQuestion)'> <ItemGroup> <ComputedQuestion Include='What do you get if you multiply six by nine' /> </ItemGroup> </Target> <ItemGroup> <ProjectReference Include='D.csproj'> <Project>{B6E7E06F-FC0B-48F1-911A-55E0E1566F00}</Project> <Name>D</Name> </ProjectReference> </ItemGroup> </Project> "; const string projectCharlieFileContents = @" <Project ToolsVersion='msbuilddefaulttoolsversion' DefaultTargets='Build' xmlns='msbuildnamespace'> <Target Name='Build' Outputs='@(ComputedAnswer)'> <ItemGroup> <ComputedAnswer Include='42' /> </ItemGroup> </Target> </Project> "; const string projectDeltaFileContents = @" <Project ToolsVersion='msbuilddefaulttoolsversion' DefaultTargets='Build' xmlns='msbuildnamespace'> <PropertyGroup> <ProjectGuid>{B6E7E06F-FC0B-48F1-911A-55E0E1566F00}</ProjectGuid> </PropertyGroup> <Target Name='Build' Outputs='@(ComputedPunctuation)'> <ItemGroup> <ComputedPunctuation Include='!!!' /> </ItemGroup> </Target> </Project> "; const string automaticProjectFileContents = @" <Project ToolsVersion='msbuilddefaulttoolsversion' DefaultTargets='compile' xmlns='msbuildnamespace'> <Target Name='compile'> <!-- Build projects to get a baseline for their output --> <MSBuild Projects='B.csproj' Targets='Build'> <Output TaskParameter='TargetOutputs' ItemName='BravoProjectOutputs' /> </MSBuild> <Message Importance='high' Text='BravoProjectOutputs: @(BravoProjectOutputs)' /> <MSBuild Projects='C.csproj' Targets='Build'> <Output TaskParameter='TargetOutputs' ItemName='CharlieProjectOutputs' /> </MSBuild> <Message Importance='high' Text='CharlieProjectOutputs: @(CharlieProjectOutputs)' /> <MSBuild Projects='D.csproj' Targets='Build'> <Output TaskParameter='TargetOutputs' ItemName='DeltaProjectOutputs' /> </MSBuild> <Message Importance='high' Text='DeltaProjectOutputs: @(DeltaProjectOutputs)' /> <PropertyGroup> <StringifiedBravoProjectOutputs>@(BravoProjectOutputs)</StringifiedBravoProjectOutputs> <StringifiedCharlieProjectOutputs>@(CharlieProjectOutputs)</StringifiedCharlieProjectOutputs> <StringifiedDeltaProjectOutputs>@(DeltaProjectOutputs)</StringifiedDeltaProjectOutputs> </PropertyGroup> <!-- Explicitly build the metaproject generated for B --> <MSBuild Projects='B.csproj.metaproj' Targets='Build'> <Output TaskParameter='TargetOutputs' ItemName='BravoMetaProjectOutputs' /> </MSBuild> <Message Importance='high' Text='BravoMetaProjectOutputs: @(BravoMetaProjectOutputs)' /> <Error Condition=` '@(BravoProjectOutputs)' != '@(BravoMetaProjectOutputs)' ` Text='Metaproj outputs must match outputs of normal project build.' /> <!-- Build the solution as a whole (which will build the metaproj and return overall outputs) --> <MSBuild Projects='MSBuildIssue.sln'> <Output TaskParameter='TargetOutputs' ItemName='SolutionProjectOutputs' /> </MSBuild> <Message Importance='high' Text='SolutionProjectOutputs: @(SolutionProjectOutputs)' /> <Error Condition=` '@(SolutionProjectOutputs->Count())' != '3' ` Text='Overall sln outputs must include outputs of each referenced project (there should be 3).' /> <Error Condition=` '@(SolutionProjectOutputs->AnyHaveMetadataValue('Identity', '$(StringifiedBravoProjectOutputs)'))' != 'true'` Text='Overall sln outputs must include outputs of normal project build of project B.' /> <Error Condition=` '@(SolutionProjectOutputs->AnyHaveMetadataValue('Identity', '$(StringifiedCharlieProjectOutputs)'))' != 'true' ` Text='Overall sln outputs must include outputs of normal project build of project C.' /> <Error Condition=` '@(SolutionProjectOutputs->AnyHaveMetadataValue('Identity', '$(StringifiedDeltaProjectOutputs)'))' != 'true' ` Text='Overall sln outputs must include outputs of normal project build of project D.' /> </Target> </Project>"; #endregion var logger = new MockLogger(); var loggers = new List<ILogger>(1) { logger }; var solutionFile = ObjectModelHelpers.CreateFileInTempProjectDirectory("MSBuildIssue.sln", solutionFileContents); ObjectModelHelpers.CreateFileInTempProjectDirectory("B.csproj", projectBravoFileContents); ObjectModelHelpers.CreateFileInTempProjectDirectory("C.csproj", projectCharlieFileContents); ObjectModelHelpers.CreateFileInTempProjectDirectory("D.csproj", projectDeltaFileContents); var solution = new SolutionFile { FullPath = solutionFile }; solution.ParseSolutionFile(); var instances = SolutionProjectGenerator.Generate(solution, null, null, new BuildEventContext(0, 0, 0, 0), null); var projectBravoMetaProject = instances[1]; Assert.False(projectBravoMetaProject.Targets.Any(kvp => kvp.Value.Outputs.Equals("@()"))); // "The outputItem parameter can be null; the Target element should not have an Outputs attribute in that case." // saves the in-memory metaproj to disk projectBravoMetaProject.ToProjectRootElement().Save(projectBravoMetaProject.FullPath); var automaticProjectFile = ObjectModelHelpers.CreateFileInTempProjectDirectory("automatic.msbuild", automaticProjectFileContents); var automaticProject = new Project(automaticProjectFile); var buildResult = automaticProject.Build(loggers); // NOTE: most of the actual assertions for this test are embedded in automaticProjectFileContents as <Error>s Assert.True(buildResult, String.Join(Environment.NewLine, logger.Errors.Select(beea => beea.Message))); }
/// <summary> /// To convert project-to-project references correctly, we need some data /// out of the solution file. If we weren't given a solution file, then /// we search the project's directory and every parent directory all the /// way up to the root for the corresponding SLN file. /// </summary> /// <owner>RGoel</owner> private void SearchForSolutionFile ( ) { error.VerifyThrow(this.solutionFile == null, "Solution file already passed in!"); error.VerifyThrow(this.projectGuid != null, "Need project Guid to find solution file."); // Start by looking for a solution file in the directory of the original project file. DirectoryInfo searchDirectory = new DirectoryInfo(Path.GetDirectoryName(Path.GetFullPath(this.oldProjectFile))); while (searchDirectory != null) { // Get a list of all the .SLN files in the current search directory. FileInfo[] slnFiles = searchDirectory.GetFiles("*.sln"); // Open each .SLN file and parse it. We're searching for a .SLN // file that contains the current project that we're converting. foreach (FileInfo slnFile in slnFiles) { // Check that the extension really is ".SLN", because the above call to // GetFiles will also return files such as blah.SLN1 and bloo.SLN2. if (0 == String.Compare(".sln", slnFile.Extension, StringComparison.OrdinalIgnoreCase)) { // Parse the .SLN file. SolutionFile solutionParser = new SolutionFile(); solutionParser.FullPath = slnFile.FullName; try { solutionParser.ParseSolutionFile(); this.conversionWarnings.AddRange(solutionParser.SolutionParserWarnings); // Determine if our current project guid (for the project we're converting) // is listed in the .SLN file. if (solutionParser.GetProjectUniqueNameByGuid(this.projectGuid) != null) { // If we found our project listed, then this is the solution we will // use to help us convert the project-to-project references. this.solutionFile = slnFile.FullName; this.solution = solutionParser; return; } } catch (InvalidProjectFileException) { // If the SLN wasn't valid, that's fine ... just skip it, and // move on to the next one. } } } // Go up one directory, and search there. Stop when we hit the root. searchDirectory = searchDirectory.Parent; } // If we don't find a solution file that contains our project, that's okay... // we can still proceed. It just means that the converted project-to-project // references won't have the relative path to the referenced project. This // may prevent command-line builds from being fully functional, but it's // not the end of the world. }