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); } }