Skip to content
This repository has been archived by the owner on Oct 4, 2021. It is now read-only.

[DotNetCore] Support alternative project type guid used by Visual Studio #5864

Merged
merged 4 commits into from
Sep 6, 2018

Conversation

mrward
Copy link
Member

@mrward mrward commented Sep 5, 2018

Visual Studio 2017 will sometimes change the project type guid used
in a solution file from the default C# project type guid to
9A19103F-16F7-4668-BE54-9A1E7A4F7556 due to a bug:

dotnet/project-system#1821

Visual Studio for Mac uses the C# project type guid which results in
the solution file being changed when it is saved. To avoid this a new
MSBuildItemType has been added for the alternative project type guid so
that the .NET Core project when loaded will have the correct project
type guid and when the solution file is saved the project type guid
will not be modified. Note that new C# .NET Core and .NET Standard
projects will continue to use the project type guid used by C#
projects AE04EC0-301F-11D3-BF4B-00C04F79EFBC which is also what Visual
Studio 2017 on Windows uses for new projects.

Fixes VSTS #677549 - Project GUID Changes When Building in VS2017 vs
Building in VS for Mac

New .NET Core projects should use the standard C# and F# project
type guids. Added tests to verify this is the case.
Visual Studio 2017 will sometimes change the project type guid used
in a solution file from the default C# project type guid to
9A19103F-16F7-4668-BE54-9A1E7A4F7556 due to a bug:

dotnet/project-system#1821

Visual Studio for Mac uses the C# project type guid which results in
the solution file being changed when it is saved. To avoid this a new
MSBuildItemType has been added for the alternative project type guid so
that the .NET Core project when loaded will have the correct project
type guid and when the solution file is saved the project type guid
will not be modified. Note that new C# .NET Core and .NET Standard
projects will continue to use the project type guid used by C#
projects AE04EC0-301F-11D3-BF4B-00C04F79EFBC which is also what Visual
Studio 2017 on Windows uses for new projects.

Fixes VSTS #677549 - Project GUID Changes When Building in VS2017 vs
Building in VS for Mac
@mrward mrward changed the title [DotNetCore] Support alternative project type guid used by Visual Studio … [DotNetCore] Support alternative project type guid used by Visual Studio Sep 5, 2018
@mrward mrward requested a review from a team September 5, 2018 17:32
Copy link
Contributor

@Therzok Therzok left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice approach! 👍

@mrward
Copy link
Member Author

mrward commented Sep 5, 2018

Seems to have broken some Core.Tests for some reason. Will have to see why that DotNetProjectType is being used for other projects.

@mrward
Copy link
Member Author

mrward commented Sep 5, 2018

Problem seems to be that the new MSBuildItemType is inserted before the usual C# one. So by default it is used when creating a new C# project since it is the first match for an MSBuildItemType that has the language set to C#.

Removing the C# language from the MSBuildItemType does not work since this is a required property. Changing it to be something other than C# breaks the language binding and language name for the project. The MSBuildProjectService's GetLanguageGuid will return the wrong DotNetProjectTypeNode.

		internal static string GetLanguageGuid (string language)
		{
			foreach (var node in GetItemTypeNodes ().OfType<DotNetProjectTypeNode> ()) {
				if (node.Language == language)
					return node.Guid;
			}
			throw new InvalidOperationException ("Language not supported: " + language);
		}

I think there needs to be some way to avoid using this MSBuildItemType by default. Make sure it is only used if the project type guid is a match. Even though it is in the MSBuildItemTypes list before the normal C# one. So something like an IsDefaultForLanguage property or something with a better name that can be used to ignore it?

	<Extension path = "/MonoDevelop/ProjectModel/MSBuildItemTypes">
		<DotNetProjectType
			id="MonoDevelop.DotNetCore.CSharpProject"
			insertbefore="MonoDevelop.CSharp.Project.CSharpProject"
			language="C#"
			isDefaultForLanguage="false"
			guid="{9A19103F-16F7-4668-BE54-9A1E7A4F7556}"
			type="MonoDevelop.CSharp.Project.CSharpProject" />
	</Extension>

My other approach seemed to be more hacky and involved the DotNetCoreObjectReader setting the TypeGuid for the project after it was loaded if it was the alternative project type guid.

@slluis
Copy link
Member

slluis commented Sep 6, 2018

Why not just use insertafter instead of insertbefore when defining MonoDevelop.DotNetCore.CSharpProject?

@mrward
Copy link
Member Author

mrward commented Sep 6, 2018

The MonoDevelop.DotNetCore.CSharpProject DotNetProjectType needs to be inserted before the standard C# one. Otherwise MonoDevelop.CSharp.Project.CSharpProject will be used since the SolutionItemTypeNode's CanHandleFile will match on the file extension:

public virtual bool CanHandleFile (string fileName, string typeGuid)
{
	if (typeGuid != null && string.Compare (typeGuid, guid, true) == 0)
		return true;
	if (!string.IsNullOrEmpty (extension) && System.IO.Path.GetExtension (fileName) == "." + extension)
		return true;
	return false;
}

Added a new isDefaultGuid property for the DotNetProjectType which
is true by default and will allow a DotNetProjectType to indicate
it should not be used by default for a language. This allows the
.NET Core addin to define a DotNetProjectType that is inserted
before the main C# one and make sure it is not used for new projects
when the ProjectService's CreateDotNetProject method is used. This
fixes several failing tests that use the ProjectService.
@mrward
Copy link
Member Author

mrward commented Sep 6, 2018

Added an isDefaultGuid property for the DotNetProjectType. This is true by default. The .NET Core addin sets it to false for the alternative .NET Core project type guid so it is ignored when ProjectService.CreateDotNetProject is used.

The alternative project type guid definition did not specify an
alias so C# was used by default. Since this DotNetProjectType was
inserted before the main C# one it could be used when creating a
new project since a match would be made of C# against the
DotNetProjectType's TypeAlias. To avoid this a unique alias is
defined. This fixes the packaging tests failing with:

1) CreateMultiPlatformProjectFromTemplateWithAndroidOnly
(MonoDevelop.Packaging.Tests.ProjectTemplateTests.CreateMultiPlatformProjectFromTemplateWithAndroidOnly)
     Expected: not null
  But was:  null

  at MonoDevelop.Packaging.Tests.ProjectTemplateTests+<CreateMultiPlatformProjectFromTemplateWithAndroidOnly>d__2.MoveNext ()
@mrward mrward merged commit f8fcfdc into master Sep 6, 2018
@mrward mrward deleted the dotnetcore-workaround-vs-changing-project-type-guids branch September 6, 2018 12:45
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants