diff --git a/src/MSBuildLocator/MSBuildLocator.cs b/src/MSBuildLocator/MSBuildLocator.cs
index e17abc2e..e2fbab52 100644
--- a/src/MSBuildLocator/MSBuildLocator.cs
+++ b/src/MSBuildLocator/MSBuildLocator.cs
@@ -139,14 +139,50 @@ public static void RegisterInstance(VisualStudioInstance instance)
///
public static void RegisterMSBuildPath(string msbuildPath)
{
- if (string.IsNullOrWhiteSpace(msbuildPath))
+ RegisterMSBuildPath(new string[] {
+ msbuildPath
+#if NET46
+ // Finds and loads NuGet assemblies if msbuildPath is in a VS installation
+ , Path.GetFullPath(Path.Combine(msbuildPath, "..", "..", "..", "Common7", "IDE", "CommonExtensions", "Microsoft", "NuGet"))
+#endif
+ });
+ }
+
+ ///
+ /// Add assembly resolution for Microsoft.Build core dlls in the current AppDomain from the specified
+ /// path.
+ ///
+ ///
+ /// Paths to directories containing a deployment of MSBuild binaries.
+ /// A minimal MSBuild deployment would be the publish result of the Microsoft.Build.Runtime package.
+ ///
+ /// In order to restore and build real projects, one needs a deployment that contains the rest of the toolchain (nuget, compilers, etc.).
+ /// Such deployments can be found in installations such as Visual Studio or dotnet CLI.
+ ///
+ public static void RegisterMSBuildPath(string[] msbuildSearchPaths)
+ {
+ if (msbuildSearchPaths.Length < 1)
{
- throw new ArgumentException("Value may not be null or whitespace", nameof(msbuildPath));
+ throw new ArgumentException("Must provide at least one search path to RegisterMSBuildPath.");
}
- if (!Directory.Exists(msbuildPath))
+ List nullOrWhiteSpaceExceptions = new List();
+ for (int i = 0; i < msbuildSearchPaths.Length; i++)
{
- throw new ArgumentException($"Directory \"{msbuildPath}\" does not exist", nameof(msbuildPath));
+ if (string.IsNullOrWhiteSpace(msbuildSearchPaths[i]))
+ {
+ nullOrWhiteSpaceExceptions.Add(new ArgumentException($"Value at position {i+1} may not be null or whitespace", nameof(msbuildSearchPaths)));
+ }
+ }
+ if (nullOrWhiteSpaceExceptions.Count > 0)
+ {
+ throw new AggregateException("Search paths for MSBuild assemblies cannot be null and must contain non-whitespace characters.", nullOrWhiteSpaceExceptions);
+ }
+
+ IEnumerable paths = msbuildSearchPaths.Where(path => !Directory.Exists(path));
+ if (paths.FirstOrDefault() == null)
+ {
+ throw new AggregateException($"A directory or directories in \"{nameof(msbuildSearchPaths)}\" do not exist", paths.Select(path => new ArgumentException($"Directory \"{path}\" does not exist", nameof(msbuildSearchPaths))));
}
if (!CanRegister)
@@ -202,12 +238,15 @@ Assembly TryLoadAssembly(AssemblyName assemblyName)
// Look in the MSBuild folder for any unresolved reference. It may be a dependency
// of MSBuild or a task.
- string targetAssembly = Path.Combine(msbuildPath, assemblyName.Name + ".dll");
- if (File.Exists(targetAssembly))
+ foreach (string msbuildPath in msbuildSearchPaths)
{
- assembly = Assembly.LoadFrom(targetAssembly);
- loadedAssemblies.Add(assemblyName.FullName, assembly);
- return assembly;
+ string targetAssembly = Path.Combine(msbuildPath, assemblyName.Name + ".dll");
+ if (File.Exists(targetAssembly))
+ {
+ assembly = Assembly.LoadFrom(targetAssembly);
+ loadedAssemblies.Add(assemblyName.FullName, assembly);
+ return assembly;
+ }
}
return null;