diff --git a/src/Microsoft.VisualStudio.SolutionPersistence/Errors.Designer.cs b/src/Microsoft.VisualStudio.SolutionPersistence/Errors.Designer.cs
index 95ecaea..d4a76b4 100644
--- a/src/Microsoft.VisualStudio.SolutionPersistence/Errors.Designer.cs
+++ b/src/Microsoft.VisualStudio.SolutionPersistence/Errors.Designer.cs
@@ -226,15 +226,6 @@ internal static string InvalidProjectReference_Args1 {
}
}
- ///
- /// Looks up a localized string similar to Missing or invalid project type guid..
- ///
- internal static string InvalidProjectType {
- get {
- return ResourceManager.GetString("InvalidProjectType", resourceCulture);
- }
- }
-
///
/// Looks up a localized string similar to ProjectType '{0}' not found..
///
diff --git a/src/Microsoft.VisualStudio.SolutionPersistence/Errors.resx b/src/Microsoft.VisualStudio.SolutionPersistence/Errors.resx
index fb39ab1..9b902f9 100644
--- a/src/Microsoft.VisualStudio.SolutionPersistence/Errors.resx
+++ b/src/Microsoft.VisualStudio.SolutionPersistence/Errors.resx
@@ -129,10 +129,6 @@
Missing or invalid scope.
Error message
-
- Missing or invalid project type guid.
- Error message
-
Syntax error.
Error message
diff --git a/src/Microsoft.VisualStudio.SolutionPersistence/Serializer/SlnV12/SlnFileV12Serializer.Reader.cs b/src/Microsoft.VisualStudio.SolutionPersistence/Serializer/SlnV12/SlnFileV12Serializer.Reader.cs
index be07021..9643bfa 100644
--- a/src/Microsoft.VisualStudio.SolutionPersistence/Serializer/SlnV12/SlnFileV12Serializer.Reader.cs
+++ b/src/Microsoft.VisualStudio.SolutionPersistence/Serializer/SlnV12/SlnFileV12Serializer.Reader.cs
@@ -525,7 +525,11 @@ private SolutionItemModel ReadProjectInfo(SolutionModel solution, ref StringToke
StringSpan projectType = tokenizer.NextToken(SlnConstants.ProjectSeparators);
// but it must end with [sep]) ... checked later.
- this.SolutionAssert(Guid.TryParse(projectType.ToString(), out Guid projectTypeId), Errors.InvalidProjectType);
+ if (!Guid.TryParse(projectType.ToString(), out Guid projectTypeId))
+ {
+ projectTypeId = Guid.Empty;
+ this.tarnished = true;
+ }
// this just skips up to Display's name "App1" first quote, position at 'A". The TrimStart is extension to allow spaces before ')';
// and yes, any characters are allowed for example // Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "App1", valid bad format :P "App1\App1.csproj",
diff --git a/test/Microsoft.VisualStudio.SolutionPersistence.Tests/Serialization/InvalidSolutions.cs b/test/Microsoft.VisualStudio.SolutionPersistence.Tests/Serialization/InvalidSolutions.cs
index 6a36ff3..39a344a 100644
--- a/test/Microsoft.VisualStudio.SolutionPersistence.Tests/Serialization/InvalidSolutions.cs
+++ b/test/Microsoft.VisualStudio.SolutionPersistence.Tests/Serialization/InvalidSolutions.cs
@@ -307,16 +307,19 @@ public async Task DuplicateProjectIdSlnxAsync()
}
///
- /// Checks that an error is thrown if the solution contains an invalid project type id.
+ /// Verifies that a malformed project type id is loaded as an empty guid without errors, and
+ /// the solution is marked as tarnished.
///
[Fact]
public async Task InvalidProjectTypeSlnAsync()
{
ResourceStream invalidProjectType = SlnAssets.LoadResource("Invalid/InvalidProjectType.sln");
- SolutionException ex = await Assert.ThrowsAsync(
- async () => _ = await SolutionSerializers.SlnFileV12.OpenAsync(invalidProjectType.Stream, CancellationToken.None));
- Assert.StartsWith(Errors.InvalidProjectType, ex.Message);
- Assert.Equal(5, ex.Line);
- Assert.Null(ex.Column);
+ SolutionModel solution = await SolutionSerializers.SlnFileV12.OpenAsync(invalidProjectType.Stream, CancellationToken.None);
+ Assert.NotNull(solution.SerializerExtension);
+ Assert.True(solution.SerializerExtension.Tarnished);
+
+ SolutionProjectModel? project = solution.FindProject("InvalidProjectType.csproj");
+ Assert.NotNull(project);
+ Assert.Equal(Guid.Empty, project.TypeId);
}
}