From b7a88ab62d2002ed7389d7db6b1facc7c8dec5a1 Mon Sep 17 00:00:00 2001 From: Kirill Osenkov Date: Wed, 21 Apr 2021 09:46:02 -0700 Subject: [PATCH] Make GenerateResource look up resgen.exe in 10.0 SDK (#6336) * Make GenerateResource look up resgen.exe in 10.0 SDK GenerateResource tests were failing when only VS 2019 and 10.0 Windows SDK is installed. I suspect the task itself would also fail if run with ExecuteAsTool. The problem is that we started look up with .NET 4.6.1 and lower. Start lookup with .NET 4.8 instead and fallback down the chain. This should still find all earlier SDKs too. Introduce latest versions of Visual Studio too. * Rollback some changes to VersionLatest. * Set the SdkToolsPath to framework 4.8 This actually fixes the unit-tests on a machine with only SDK 10.0 installed. --- .../net/Microsoft.Build.Utilities.Core.cs | 2 + .../Microsoft.Build.Utilities.Core.cs | 2 + src/Shared/FrameworkLocationHelper.cs | 34 ++++++++++- .../GenerateResourceOutOfProc_Tests.cs | 2 +- src/Tasks/GenerateResource.cs | 13 +++- src/Utilities/ToolLocationHelper.cs | 60 +++++++++++-------- 6 files changed, 82 insertions(+), 31 deletions(-) diff --git a/ref/Microsoft.Build.Utilities.Core/net/Microsoft.Build.Utilities.Core.cs b/ref/Microsoft.Build.Utilities.Core/net/Microsoft.Build.Utilities.Core.cs index e435979d2b2..a8564cf317b 100644 --- a/ref/Microsoft.Build.Utilities.Core/net/Microsoft.Build.Utilities.Core.cs +++ b/ref/Microsoft.Build.Utilities.Core/net/Microsoft.Build.Utilities.Core.cs @@ -600,5 +600,7 @@ public enum VisualStudioVersion Version140 = 3, Version150 = 4, VersionLatest = 4, + Version160 = 5, + Version170 = 6, } } diff --git a/ref/Microsoft.Build.Utilities.Core/netstandard/Microsoft.Build.Utilities.Core.cs b/ref/Microsoft.Build.Utilities.Core/netstandard/Microsoft.Build.Utilities.Core.cs index d77c4295057..9d7111dfe72 100644 --- a/ref/Microsoft.Build.Utilities.Core/netstandard/Microsoft.Build.Utilities.Core.cs +++ b/ref/Microsoft.Build.Utilities.Core/netstandard/Microsoft.Build.Utilities.Core.cs @@ -434,5 +434,7 @@ public enum VisualStudioVersion Version140 = 3, Version150 = 4, VersionLatest = 4, + Version160 = 5, + Version170 = 6, } } diff --git a/src/Shared/FrameworkLocationHelper.cs b/src/Shared/FrameworkLocationHelper.cs index 006e0587bf1..e567fc1f64c 100644 --- a/src/Shared/FrameworkLocationHelper.cs +++ b/src/Shared/FrameworkLocationHelper.cs @@ -66,9 +66,11 @@ internal static class FrameworkLocationHelper internal static readonly Version visualStudioVersion120 = new Version(12, 0); internal static readonly Version visualStudioVersion140 = new Version(14, 0); internal static readonly Version visualStudioVersion150 = new Version(15, 0); + internal static readonly Version visualStudioVersion160 = new Version(16, 0); + internal static readonly Version visualStudioVersion170 = new Version(17, 0); // keep this up-to-date; always point to the latest visual studio version. - internal static readonly Version visualStudioVersionLatest = visualStudioVersion150; + internal static readonly Version visualStudioVersionLatest = visualStudioVersion160; private const string dotNetFrameworkRegistryPath = "SOFTWARE\\Microsoft\\.NETFramework"; private const string dotNetFrameworkSetupRegistryPath = "SOFTWARE\\Microsoft\\NET Framework Setup\\NDP"; @@ -286,6 +288,25 @@ internal static class FrameworkLocationHelper dotNetFrameworkVersion472, dotNetFrameworkVersion48, }), + + // VS16 + new VisualStudioSpec(visualStudioVersion160, "NETFXSDK\\{0}", "v10.0", "InstallationFolder", new [] + { + dotNetFrameworkVersion11, + dotNetFrameworkVersion20, + dotNetFrameworkVersion35, + dotNetFrameworkVersion40, + dotNetFrameworkVersion45, + dotNetFrameworkVersion451, + dotNetFrameworkVersion452, + dotNetFrameworkVersion46, + dotNetFrameworkVersion461, + dotNetFrameworkVersion462, + dotNetFrameworkVersion47, + dotNetFrameworkVersion471, + dotNetFrameworkVersion472, + dotNetFrameworkVersion48, + }), }; #if FEATURE_WIN32_REGISTRY @@ -320,6 +341,17 @@ internal static class FrameworkLocationHelper { (dotNetFrameworkVersion471, visualStudioVersion150), (dotNetFrameworkVersion47, visualStudioVersion150) }, { (dotNetFrameworkVersion472, visualStudioVersion150), (dotNetFrameworkVersion471, visualStudioVersion150) }, { (dotNetFrameworkVersion48, visualStudioVersion150), (dotNetFrameworkVersion472, visualStudioVersion150) }, + + // VS16 + { (dotNetFrameworkVersion451, visualStudioVersion160), (dotNetFrameworkVersion45, visualStudioVersion160) }, + { (dotNetFrameworkVersion452, visualStudioVersion160), (dotNetFrameworkVersion451, visualStudioVersion160) }, + { (dotNetFrameworkVersion46, visualStudioVersion160), (dotNetFrameworkVersion451, visualStudioVersion160) }, + { (dotNetFrameworkVersion461, visualStudioVersion160), (dotNetFrameworkVersion46, visualStudioVersion160) }, + { (dotNetFrameworkVersion462, visualStudioVersion160), (dotNetFrameworkVersion461, visualStudioVersion160) }, + { (dotNetFrameworkVersion47, visualStudioVersion160), (dotNetFrameworkVersion462, visualStudioVersion160) }, + { (dotNetFrameworkVersion471, visualStudioVersion160), (dotNetFrameworkVersion47, visualStudioVersion160) }, + { (dotNetFrameworkVersion472, visualStudioVersion160), (dotNetFrameworkVersion471, visualStudioVersion160) }, + { (dotNetFrameworkVersion48, visualStudioVersion160), (dotNetFrameworkVersion472, visualStudioVersion160) }, }; #endif // FEATURE_WIN32_REGISTRY diff --git a/src/Tasks.UnitTests/ResourceHandling/GenerateResourceOutOfProc_Tests.cs b/src/Tasks.UnitTests/ResourceHandling/GenerateResourceOutOfProc_Tests.cs index 3c304324122..6d055df7140 100644 --- a/src/Tasks.UnitTests/ResourceHandling/GenerateResourceOutOfProc_Tests.cs +++ b/src/Tasks.UnitTests/ResourceHandling/GenerateResourceOutOfProc_Tests.cs @@ -3015,7 +3015,7 @@ public static GenerateResource CreateTaskOutOfProc(ITestOutputHelper output) { GenerateResource t = CreateTask(output); t.ExecuteAsTool = true; - t.SdkToolsPath = ToolLocationHelper.GetPathToDotNetFrameworkSdk(TargetDotNetFrameworkVersion.VersionLatest); + t.SdkToolsPath = ToolLocationHelper.GetPathToDotNetFrameworkSdk(TargetDotNetFrameworkVersion.Version48); return t; } diff --git a/src/Tasks/GenerateResource.cs b/src/Tasks/GenerateResource.cs index 7a3ad571bda..bc15a0328a1 100644 --- a/src/Tasks/GenerateResource.cs +++ b/src/Tasks/GenerateResource.cs @@ -1065,13 +1065,20 @@ private bool ComputePathToResGen() if (String.IsNullOrEmpty(_sdkToolsPath)) { - _resgenPath = ToolLocationHelper.GetPathToDotNetFrameworkSdkFile("resgen.exe", TargetDotNetFrameworkVersion.Version35); + // Important: the GenerateResource task is declared twice in Microsoft.Common.CurrentVersion.targets: + // https://github.com/dotnet/msbuild/blob/369631b4b21ef485f4d6f35e16b0c839a971b0e9/src/Tasks/Microsoft.Common.CurrentVersion.targets#L3177-L3178 + // First for CLR >= 4.0, where SdkToolsPath is passed $(ResgenToolPath) which in turn is set to + // $(TargetFrameworkSDKToolsDirectory). + // But for CLR < 4.0 the SdkToolsPath is not passed, so we need to explicitly assume 3.5: + var version = TargetDotNetFrameworkVersion.Version35; + + _resgenPath = ToolLocationHelper.GetPathToDotNetFrameworkSdkFile("resgen.exe", version); if (_resgenPath == null && ExecuteAsTool) { Log.LogErrorWithCodeFromResources("General.PlatformSDKFileNotFound", "resgen.exe", - ToolLocationHelper.GetDotNetFrameworkSdkInstallKeyValue(TargetDotNetFrameworkVersion.Version35), - ToolLocationHelper.GetDotNetFrameworkSdkRootRegistryKey(TargetDotNetFrameworkVersion.Version35)); + ToolLocationHelper.GetDotNetFrameworkSdkInstallKeyValue(version), + ToolLocationHelper.GetDotNetFrameworkSdkRootRegistryKey(version)); } } else diff --git a/src/Utilities/ToolLocationHelper.cs b/src/Utilities/ToolLocationHelper.cs index d2473b7f3e5..1b6d83c2caa 100644 --- a/src/Utilities/ToolLocationHelper.cs +++ b/src/Utilities/ToolLocationHelper.cs @@ -130,30 +130,40 @@ public enum TargetDotNetFrameworkVersion public enum VisualStudioVersion { /// - /// Visual Studio 2010 and SP1 + /// Visual Studio 2010 (Dev10) and SP1 /// Version100, /// - /// Visual Studio Dev11 + /// Visual Studio 2012 (Dev11) /// Version110, /// - /// Visual Studio Dev12 + /// Visual Studio 2013 (Dev12) /// Version120, /// - /// Visual Studio Dev14 + /// Visual Studio 2015 (Dev14) /// Version140, /// - /// Visual Studio Dev15 + /// Visual Studio 2017 (Dev15) /// Version150, + /// + /// Visual Studio 2019 (Dev16) + /// + Version160, + + /// + /// Visual Studio "Dev17" + /// + Version170, + // keep this up-to-date; always point to the last entry. /// /// The latest version available at the time of release @@ -2052,26 +2062,22 @@ private static Version TargetDotNetFrameworkVersionToSystemVersion(TargetDotNetF private static Version VisualStudioVersionToSystemVersion(VisualStudioVersion version) { - switch (version) + return version switch { - case VisualStudioVersion.Version100: - return FrameworkLocationHelper.visualStudioVersion100; - - case VisualStudioVersion.Version110: - return FrameworkLocationHelper.visualStudioVersion110; - - case VisualStudioVersion.Version120: - return FrameworkLocationHelper.visualStudioVersion120; - - case VisualStudioVersion.Version140: - return FrameworkLocationHelper.visualStudioVersion140; - - case VisualStudioVersion.Version150: - return FrameworkLocationHelper.visualStudioVersion150; + VisualStudioVersion.Version100 => FrameworkLocationHelper.visualStudioVersion100, + VisualStudioVersion.Version110 => FrameworkLocationHelper.visualStudioVersion110, + VisualStudioVersion.Version120 => FrameworkLocationHelper.visualStudioVersion120, + VisualStudioVersion.Version140 => FrameworkLocationHelper.visualStudioVersion140, + VisualStudioVersion.Version150 => FrameworkLocationHelper.visualStudioVersion150, + VisualStudioVersion.Version160 => FrameworkLocationHelper.visualStudioVersion160, + VisualStudioVersion.Version170 => FrameworkLocationHelper.visualStudioVersion170, + _ => Unsupported() + }; - default: - ErrorUtilities.ThrowArgument("ToolLocationHelper.UnsupportedVisualStudioVersion", version); - return null; + Version Unsupported() + { + ErrorUtilities.ThrowArgument("ToolLocationHelper.UnsupportedVisualStudioVersion", version); + return null; } } @@ -3250,7 +3256,8 @@ internal static string ChainReferenceAssemblyPath(string targetFrameworkDirector /// /// File name to locate in the .NET Framework SDK directory /// Path string. - public static string GetPathToDotNetFrameworkSdkFile(string fileName) => GetPathToDotNetFrameworkSdkFile(fileName, TargetDotNetFrameworkVersion.Latest); + public static string GetPathToDotNetFrameworkSdkFile(string fileName) + => GetPathToDotNetFrameworkSdkFile(fileName, TargetDotNetFrameworkVersion.Latest); /// /// Get a fully qualified path to a file in the .NET Framework SDK. Error if the .NET Framework SDK can't be found. @@ -3261,7 +3268,8 @@ internal static string ChainReferenceAssemblyPath(string targetFrameworkDirector /// File name to locate in the .NET Framework SDK directory /// Version of the targeted .NET Framework /// Path string. - public static string GetPathToDotNetFrameworkSdkFile(string fileName, TargetDotNetFrameworkVersion version) => GetPathToDotNetFrameworkSdkFile(fileName, version, VisualStudioVersion.VersionLatest); + public static string GetPathToDotNetFrameworkSdkFile(string fileName, TargetDotNetFrameworkVersion version) + => GetPathToDotNetFrameworkSdkFile(fileName, version, VisualStudioVersion.VersionLatest); /// /// Get a fully qualified path to a file in the .NET Framework SDK. Error if the .NET Framework SDK can't be found. @@ -3276,7 +3284,7 @@ public static string GetPathToDotNetFrameworkSdkFile(string fileName, TargetDotN version, visualStudioVersion, UtilitiesDotNetFrameworkArchitecture.Current, - true /* If the file is not found for the current architecture, it's OK to follow fallback mechanisms. */ + canFallBackIfNecessary: true /* If the file is not found for the current architecture, it's OK to follow fallback mechanisms. */ ); ///