diff --git a/src/MSBuild.UnitTests/XMake_Tests.cs b/src/MSBuild.UnitTests/XMake_Tests.cs
index a8d752ac5dd..f4eafd483a6 100644
--- a/src/MSBuild.UnitTests/XMake_Tests.cs
+++ b/src/MSBuild.UnitTests/XMake_Tests.cs
@@ -2879,6 +2879,35 @@ public void EndToEndMinimumMessageImportance_OutOfProc(string arguments, Message
success.ShouldBeTrue();
}
+ [Theory]
+ [InlineData("-v:diag -m:1 -tl:off")]
+ [InlineData("-v:diag -m -tl:off")]
+ [InlineData("-v:m -m:1 -tl:off")]
+ [InlineData("-v:m -m -tl:off")]
+ [InlineData("-v:diag -m:1 -tl:on")]
+ [InlineData("-v:diag -m -tl:on")]
+ [InlineData("-v:m -m:1 -tl:on")]
+ [InlineData("-v:m -m -tl:on")]
+ public void PreprocessProjectWell(string arguments)
+ {
+ string projectContents = ObjectModelHelpers.CleanupFileContents(
+ $"""
+
+
+ netstandard2.0
+
+
+ """);
+ using TestEnvironment testEnvironment = TestEnvironment.Create();
+ TransientTestProjectWithFiles testProject = testEnvironment.CreateTestProjectWithFiles(projectContents);
+ var preprocessFile = Path.Combine(testProject.TestRoot, "Preprocess.xml");
+ arguments += $" -pp:{preprocessFile}";
+
+ string output = RunnerUtilities.ExecBootstrapedMSBuild($"{arguments} \"{testProject.ProjectFile}\"", out bool success, outputHelper: _output, attachProcessId: false);
+ success.ShouldBeTrue();
+ File.Exists(preprocessFile).ShouldBeTrue();
+ }
+
#if FEATURE_ASSEMBLYLOADCONTEXT
///
/// Ensure that tasks get loaded into their own .
diff --git a/src/MSBuild/XMake.cs b/src/MSBuild/XMake.cs
index b1e2f485a27..dc0f4ba8bef 100644
--- a/src/MSBuild/XMake.cs
+++ b/src/MSBuild/XMake.cs
@@ -1393,7 +1393,8 @@ .. distributedLoggerRecords.Select(d => d.CentralLogger)
projectCollection = new ProjectCollection(
globalProperties,
- evaluationLoggers,
+ // When using the switch -preprocess, the project isn't built. No logger is needed to pass to avoid the crash when loading project.
+ isPreprocess ? null : evaluationLoggers,
null,
toolsetDefinitionLocations,
cpuCount,