From b4dc1795f1c1f891cf1db1c7301b3ba8416b40fb Mon Sep 17 00:00:00 2001 From: Nathan Mytelka Date: Mon, 20 Sep 2021 10:10:49 -0700 Subject: [PATCH 1/3] Find x64 MSBuild from Locator --- src/MSBuildLocator/MSBuildLocator.cs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/MSBuildLocator/MSBuildLocator.cs b/src/MSBuildLocator/MSBuildLocator.cs index 9c9efa48..ae88f578 100644 --- a/src/MSBuildLocator/MSBuildLocator.cs +++ b/src/MSBuildLocator/MSBuildLocator.cs @@ -209,6 +209,27 @@ public static void RegisterMSBuildPath(string[] msbuildSearchPaths) // AssemblyResolve event can fire multiple times for the same assembly, so keep track of what's already been loaded. var loadedAssemblies = new Dictionary(); + // MSBuild can be loaded from the x86 or x64 folder. Before 17.0, it looked next to the executing assembly in some cases and constructed a path that assumed x86 in others. + // This overrides the latter assumption to let it find the right MSBuild. + foreach (string path in msbuildSearchPaths) + { + string msbuildExe = Path.Combine(path, "MSBuild.exe"); + if (File.Exists(msbuildExe)) + { + Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", msbuildExe); + break; + } + else + { + string msbuildDll = Path.Combine(path, "MSBuild.dll"); + if (File.Exists(msbuildDll)) + { + Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", msbuildDll); + break; + } + } + } + // Saving the handler in a static field so it can be unregistered later. #if NET46 s_registeredHandler = (_, eventArgs) => From 3e9aee3da392d09d3854bb70677a433e60e79744 Mon Sep 17 00:00:00 2001 From: Nathan Mytelka Date: Tue, 21 Sep 2021 08:27:44 -0700 Subject: [PATCH 2/3] PR Comments --- src/MSBuildLocator/MSBuildLocator.cs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/MSBuildLocator/MSBuildLocator.cs b/src/MSBuildLocator/MSBuildLocator.cs index ae88f578..74574f8c 100644 --- a/src/MSBuildLocator/MSBuildLocator.cs +++ b/src/MSBuildLocator/MSBuildLocator.cs @@ -3,11 +3,11 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Text; -using System.Threading; #if NETCOREAPP using System.Runtime.Loader; @@ -216,17 +216,15 @@ public static void RegisterMSBuildPath(string[] msbuildSearchPaths) string msbuildExe = Path.Combine(path, "MSBuild.exe"); if (File.Exists(msbuildExe)) { - Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", msbuildExe); - break; - } - else - { - string msbuildDll = Path.Combine(path, "MSBuild.dll"); - if (File.Exists(msbuildDll)) + if (FileVersionInfo.GetVersionInfo(msbuildExe).FileMajorPart < 17) { - Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", msbuildDll); - break; + if (Path.GetDirectoryName(msbuildExe).EndsWith(@"\amd64", StringComparison.OrdinalIgnoreCase)) + { + msbuildExe = Path.Combine(path.Substring(0, path.Length - 6), "MSBuild.exe"); + } + Environment.SetEnvironmentVariable("MSBUILD_EXE_PATH", msbuildExe); } + break; } } From 968b89745482b810240da666cac75d97347ac520 Mon Sep 17 00:00:00 2001 From: Nathan Mytelka Date: Mon, 11 Oct 2021 12:00:57 -0700 Subject: [PATCH 3/3] Check for .NET Framework Actually checking for NET46 because that's the only Framework version in the TargetFrameworks, though it would be good to change that eventually. --- src/MSBuildLocator/MSBuildLocator.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/MSBuildLocator/MSBuildLocator.cs b/src/MSBuildLocator/MSBuildLocator.cs index 74574f8c..c0651cbe 100644 --- a/src/MSBuildLocator/MSBuildLocator.cs +++ b/src/MSBuildLocator/MSBuildLocator.cs @@ -209,6 +209,7 @@ public static void RegisterMSBuildPath(string[] msbuildSearchPaths) // AssemblyResolve event can fire multiple times for the same assembly, so keep track of what's already been loaded. var loadedAssemblies = new Dictionary(); +#if NET46 // MSBuild can be loaded from the x86 or x64 folder. Before 17.0, it looked next to the executing assembly in some cases and constructed a path that assumed x86 in others. // This overrides the latter assumption to let it find the right MSBuild. foreach (string path in msbuildSearchPaths) @@ -227,6 +228,7 @@ public static void RegisterMSBuildPath(string[] msbuildSearchPaths) break; } } +#endif // Saving the handler in a static field so it can be unregistered later. #if NET46