Created
November 18, 2016 16:23
-
-
Save damianh/0215b54dbb4b2570461b6d2866acd284 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Runtime.InteropServices; | |
using Microsoft.VisualStudio.Setup.Configuration; | |
namespace LocateMSBuild | |
{ | |
public class Instance | |
{ | |
private static ISetupConfiguration GetSetupConfiguration() | |
{ | |
ISetupConfiguration setupConfiguration; | |
try | |
{ | |
setupConfiguration = new SetupConfiguration(); | |
} | |
catch (COMException comException) when (comException.HResult == unchecked((int)0x80040154)) | |
{ | |
Console.WriteLine("COM registration is missing, Visual Studio may not be installed correctly"); | |
throw; | |
} | |
return setupConfiguration; | |
} | |
private static IEnumerable<ISetupInstance> EnumerateVisualStudioInstances() | |
{ | |
var setupConfiguration = GetSetupConfiguration() as ISetupConfiguration2; | |
var instanceEnumerator = setupConfiguration.EnumAllInstances(); | |
var instances = new ISetupInstance[3]; | |
var instancesFetched = 0; | |
instanceEnumerator.Next(instances.Length, instances, out instancesFetched); | |
if (instancesFetched == 0) | |
{ | |
throw new Exception("There were no instances of Visual Studio 15.0 or later found."); | |
} | |
do | |
{ | |
for (var index = 0; index < instancesFetched; index++) | |
{ | |
yield return instances[index]; | |
} | |
instanceEnumerator.Next(instances.Length, instances, out instancesFetched); | |
} | |
while (instancesFetched != 0); | |
} | |
private static ISetupInstance LocateVisualStudioInstance(string vsProductVersion, HashSet<string> requiredPackageIds) | |
{ | |
var instances = EnumerateVisualStudioInstances().Where((instance) => instance.GetInstallationVersion().StartsWith(vsProductVersion)); | |
var instanceFoundWithInvalidState = false; | |
foreach (ISetupInstance2 instance in instances.OrderByDescending(i => i.GetInstallationVersion())) | |
{ | |
var packages = instance.GetPackages() | |
.Where((package) => requiredPackageIds.Contains(package.GetId())); | |
if (packages.Count() != requiredPackageIds.Count) | |
{ | |
continue; | |
} | |
const InstanceState minimumRequiredState = InstanceState.Local | InstanceState.Registered; | |
var state = instance.GetState(); | |
if ((state & minimumRequiredState) == minimumRequiredState) | |
{ | |
return instance; | |
} | |
Console.WriteLine($"An instance matching the specified requirements but had an invalid state. (State: {state})"); | |
instanceFoundWithInvalidState = true; | |
} | |
throw new Exception(instanceFoundWithInvalidState ? | |
"An instance matching the specified requirements was found but it was in an invalid state." : | |
"There were no instances of Visual Studio 15.0 or later found that match the specified requirements."); | |
} | |
public static string GetMsBuildInstallPath() | |
{ | |
var instance = LocateVisualStudioInstance("15.0", new HashSet<string>(new[] { "Microsoft.Component.MSBuild" })) as ISetupInstance2; | |
var installationPath = instance.GetInstallationPath(); | |
return Path.Combine(installationPath, "MSBuild", "15.0"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Using in Powershell