private string GetVSInstallPath() { var dllLocation = Path.GetDirectoryName(typeof(CoverageLogger).GetTypeInfo().Assembly.Location); dllLocation = Path.Combine(dllLocation, IntPtr.Size == 4 ? SetupInteropx86 : SetupInteropx64); var setupInstance = ComOperations.CreateInstanceFrom( dllLocation, typeof(SetupConfiguration).GetTypeInfo().GUID, typeof(ISetupConfiguration).GetTypeInfo().GUID) as ISetupConfiguration; IEnumSetupInstances vsInstances = setupInstance?.EnumInstances(); if (vsInstances != null) { vsInstances.Next(1, out ISetupInstance currentInstance, out int fetched); while (currentInstance != null && fetched == 1) { string installRoot = Path.GetFullPath(currentInstance.GetInstallationPath()); if (!string.IsNullOrEmpty(installRoot)) { return(installRoot); } vsInstances.Next(1, out currentInstance, out fetched); } } return(string.Empty); }
public static void PrintJson() { ISetupConfiguration query = new SetupConfiguration(); ISetupConfiguration2 query2 = (ISetupConfiguration2)query; IEnumSetupInstances e = query2.EnumAllInstances(); int pceltFetched; ISetupInstance2[] rgelt = new ISetupInstance2[1]; List <string> instances = new List <string>(); while (true) { e.Next(1, rgelt, out pceltFetched); if (pceltFetched <= 0) { Console.WriteLine(String.Format("[{0}]", string.Join(",", instances.ToArray()))); return; } try { instances.Add(InstanceJson(rgelt[0])); } catch (COMException) { // Ignore instances that can't be queried. } } }
public static List <VSInstance> QueryEx(params string[] args) { List <VSInstance> insts = new List <VSInstance>(); ISetupConfiguration query = new SetupConfiguration(); ISetupConfiguration2 query2 = (ISetupConfiguration2)query; IEnumSetupInstances e = query2.EnumAllInstances(); ISetupInstance2[] rgelt = new ISetupInstance2[1]; int pceltFetched; e.Next(1, rgelt, out pceltFetched); while (pceltFetched > 0) { ISetupInstance2 raw = rgelt[0]; insts.Add(ParseInstance(raw)); e.Next(1, rgelt, out pceltFetched); } foreach (VSInstance inst in insts.ToArray()) { foreach (string key in args) { if (!inst.JSONBool(key)) { insts.Remove(inst); } } if (Array.IndexOf(args, "Packages") == -1) { inst.Remove("Packages"); } } return(insts); }
public static SetupInstance GetSetupInstance() { SetupInstance instance = null; #pragma warning disable CS0219 // Variable is assigned but its value is never used int exHResult = 0; #pragma warning restore CS0219 // Variable is assigned but its value is never used ISetupConfiguration2 configuration = SetupEnvironment.GetQuery(); IEnumSetupInstances enumerator = configuration.EnumAllInstances(); int fetched; ISetupInstance[] instances = new ISetupInstance[1]; do { enumerator.Next(1, instances, out fetched); if (fetched > 0) { instance = SetupInstance.From((ISetupInstance2)instances[0]); break; } }while (fetched > 0); { exHResult = 0; } return(instance); }
public static void Query() { ISetupConfiguration query = new SetupConfiguration(); ISetupConfiguration2 query2 = (ISetupConfiguration2)query; IEnumSetupInstances e = query2.EnumAllInstances(); int pceltFetched; ISetupInstance2[] rgelt = new ISetupInstance2[1]; StringBuilder log = new StringBuilder(); while (true) { e.Next(1, rgelt, out pceltFetched); if (pceltFetched <= 0) { Console.WriteLine(String.Format("{{\"log\":\"{0}\"}}", log.ToString())); return; } if (CheckInstance(rgelt[0], ref log)) { return; } } }
public static bool FindVSVersion() { try { SetupConfiguration Setup = new SetupConfiguration(); IEnumSetupInstances Enumerator = Setup.EnumAllInstances(); ISetupInstance[] Instances = new ISetupInstance[1]; for (; ;) { int NumFetched; Enumerator.Next(1, Instances, out NumFetched); if (NumFetched == 0) { break; } ISetupInstance2 Instance = (ISetupInstance2)Instances[0]; if ((Instance.GetState() & InstanceState.Local) == InstanceState.Local) { string VersionString = Instance.GetDisplayName(); if (VersionString.Contains("19")) { return(true); } } } } catch { } return(true); }
/// <summary> /// Gets launchable instances of Visual Studio on the machine. /// </summary> /// <returns>An <see cref="IEnumerable{VisualStudioInstance}" /> of all launchable instances of Visual Studio.</returns> public static IEnumerable <VisualStudioInstance> GetLaunchableInstances() { int fetched = 1; ISetupInstance[] instances = new ISetupInstance[fetched]; IEnumSetupInstances enumerator = SetupConfiguration.EnumInstances(); do { enumerator.Next(fetched, instances, out fetched); if (fetched > 0) { ISetupInstance2 instance; try { instance = instances[0] as ISetupInstance2; } catch (COMException e) when(e.HResult == unchecked ((int)0x80070490)) { continue; } if (instance != null) { yield return(new VisualStudioInstance(instance)); } } }while (fetched > 0); }
/// <summary> /// Enumerates the list of installed VS instances and returns the first one /// matching <see cref="MajorVersion"/>. Right now there is no way for the user to influence /// which version to choose if multiple installed version have the same major, /// e.g. VS2017 installed as Enterprise and Professional. /// </summary> /// <returns> /// Path to the top level directory of the Visual studio installation directory, /// e.g. <c>C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise</c> /// </returns> protected string GetVsInstallDir() { if (myVisualStudioInstallationPath != null) { return(myVisualStudioInstallationPath); } var setupConfiguration = (ISetupConfiguration2)GetSetupConfiguration(); IEnumSetupInstances instancesEnumerator = setupConfiguration.EnumAllInstances(); int fetched; var instances = new ISetupInstance[1]; while (true) { instancesEnumerator.Next(1, instances, out fetched); if (fetched <= 0) { break; } var instance = (ISetupInstance2)instances[0]; if (!Version.TryParse(instance.GetInstallationVersion(), out Version version)) { Trace.TraceError("Failed to retrieve version. Skipping VS instance."); continue; } if (version.Major != myMajorVersion) { continue; } if (myVisualStudioInstallationPath != null) { Trace.TraceWarning("Already found a Visual Studio version. Ignoring version at {0}", instance.GetInstallationPath()); continue; } var state = instance.GetState(); if (state.HasFlag(InstanceState.Local) && state.HasFlag(InstanceState.Registered)) { myVisualStudioInstallationPath = instance.GetInstallationPath(); Trace.TraceInformation("Found matching Visual Studio version at {0}", myVisualStudioInstallationPath); } else { Trace.TraceWarning("Ignoring incomplete Visual Studio version at {0}", instance.GetInstallationPath()); } } return(myVisualStudioInstallationPath); }
private string GetExeToolPathFromSetupConfiguration(ILogger logger) { string toolPath = null; logger.LogDebug(Resources.CONV_DIAG_LocatingCodeCoverageToolSetupConfiguration); ISetupConfiguration configurationQuery = setupConfigurationFactory.GetSetupConfigurationQuery(); if (configurationQuery != null) { IEnumSetupInstances instanceEnumerator = configurationQuery.EnumInstances(); int fetched; ISetupInstance[] tempInstance = new ISetupInstance[1]; List <ISetupInstance2> instances = new List <ISetupInstance2>(); //Enumerate the configuration instances do { instanceEnumerator.Next(1, tempInstance, out fetched); if (fetched > 0) { ISetupInstance2 instance = (ISetupInstance2)tempInstance[0]; if (instance.GetPackages().Any(p => p.GetId() == CodeCoverageInstallationPackage)) { //Store instances that have code coverage package installed instances.Add((ISetupInstance2)tempInstance[0]); } } } while (fetched > 0); if (instances.Count > 1) { logger.LogDebug(Resources.CONV_DIAG_MultipleVsVersionsInstalled, string.Join(", ", instances.Select(i => i.GetInstallationVersion()))); } //Get the installation path for the latest visual studio found var visualStudioPath = instances.OrderByDescending(i => i.GetInstallationVersion()) .Select(i => i.GetInstallationPath()) .FirstOrDefault(); if (visualStudioPath != null) { toolPath = Path.Combine(visualStudioPath, TeamToolPathandExeName); } } else { logger.LogDebug(Resources.CONV_DIAG_SetupConfigurationNotSupported); } return(toolPath); }
public static VisualStudioInstance GetVisualStudioInstance() { if (VisualStudioInstanceList == null) { VisualStudioInstanceList = new List <VisualStudioInstance>(); try { ISetupConfiguration2 setupConfiguration = new SetupConfigurationClass() as ISetupConfiguration2; if (setupConfiguration != null) { IEnumSetupInstances instanceEnumerator = setupConfiguration.EnumAllInstances(); ISetupInstance2[] instances = new ISetupInstance2[3]; instanceEnumerator.Next(instances.Length, instances, out var instancesFetched); if (instancesFetched == 0) { return(null); } do { for (int i = 0; i < instancesFetched; i++) { VisualStudioInstanceList.Add(new VisualStudioInstance(instances[i])); } instanceEnumerator.Next(instances.Length, instances, out instancesFetched); }while (instancesFetched != 0); } } catch { } } foreach (VisualStudioInstance instance in VisualStudioInstanceList) { if ( instance.HasRequiredDependency && instance.DisplayName.EndsWith("2019", StringComparison.OrdinalIgnoreCase) // HACK ) { return(instance); } } return(null); }
private IEnumerable <VisualStudioInstance> EnumInstances(IEnumSetupInstances enumerator) { int fetched = 1; ISetupInstance[] instances = new ISetupInstance[fetched]; do { enumerator.Next(fetched, instances, out fetched); if (fetched > 0) { yield return(new VisualStudioInstance(instances[0] as ISetupInstance2)); } }while (fetched > 0); }
public static VisualStudioInstance GetVisualStudioInstance() { if (VisualStudioInstanceList == null) { VisualStudioInstanceList = new List <VisualStudioInstance>(); try { if (new SetupConfigurationClass() is ISetupConfiguration2 setupConfiguration) { IEnumSetupInstances instanceEnumerator = setupConfiguration.EnumAllInstances(); ISetupInstance2[] instances = new ISetupInstance2[3]; instanceEnumerator.Next(instances.Length, instances, out var instancesFetched); if (instancesFetched == 0) { return(null); } do { for (int i = 0; i < instancesFetched; i++) { VisualStudioInstanceList.Add(new VisualStudioInstance(instances[i])); } instanceEnumerator.Next(instances.Length, instances, out instancesFetched); }while (instancesFetched != 0); } } catch { } } foreach (VisualStudioInstance instance in VisualStudioInstanceList) { if (instance.HasRequiredDependency) { return(instance); } } return(null); }
private static IEnumerable <ISetupInstance> GetSetupInstances() { ISetupConfiguration setupConfiguration = new SetupConfiguration(); IEnumSetupInstances enumerator = setupConfiguration.EnumInstances(); int count; do { ISetupInstance[] setupInstances = new ISetupInstance[1]; enumerator.Next(1, setupInstances, out count); if (count == 1 && setupInstances != null && setupInstances.Length == 1 && setupInstances[0] != null) { yield return(setupInstances[0]); } }while (count == 1); }
private string GetVS2019Path() { try { SetupConfiguration setupConfiguration = new SetupConfiguration(); ISetupInstance[] iSetupInstance = new ISetupInstance[1]; IEnumSetupInstances iEnumSetupInstances = setupConfiguration.EnumAllInstances(); while (true) { { int test; iEnumSetupInstances.Next(1, iSetupInstance, out test); if (test == 0) { break; } } ISetupInstance2 iSetupInstance2 = (ISetupInstance2)iSetupInstance[0]; if ((iSetupInstance2.GetState() & InstanceState.Local) == InstanceState.Local) { string InstallationVersion = iSetupInstance2.GetInstallationVersion(); if (!string.IsNullOrEmpty(InstallationVersion)) { string vs = InstallationVersion.Remove(InstallationVersion.IndexOf('.')); if (vs == "16") { return(iSetupInstance2.GetInstallationPath()); } } } } } catch { } throw new Exception("Visual Studio 2019 неустановлена."); return(null); }
private static IEnumerable <IVisualStudioInfo> DetectNewVisualStudios() { SetupConfiguration configuration; try { configuration = new SetupConfiguration(); } catch (COMException ex) { // class not registered, no VS2017+ installations if ((uint)ex.HResult == 0x80040154) { yield break; } throw; } IEnumSetupInstances e = configuration.EnumAllInstances(); int fetched; ISetupInstance[] instances = new ISetupInstance[1]; do { e.Next(1, instances, out fetched); if (fetched <= 0) { continue; } ISetupInstance2 instance2 = (ISetupInstance2)instances[0]; string filename = Path.Combine(instance2.GetInstallationPath(), @"Common7\IDE\devenv.exe"); if (File.Exists(filename)) { yield return(new VisualStudio2017Info(Version.Parse(instance2.GetInstallationVersion()), instance2.GetDisplayName(), filename)); } }while (fetched > 0); }
/// <summary> /// Returns the list of <seealso cref="VisualStudioInstance"/> representing the installed /// Visual Studio instances on the machine. /// </summary> /// <param name="lcid"> /// The local id to use for returning internationalized strings. /// </param> /// <param name="includeIncompleteInstances"> /// If true, does all instances, even those that are incomplete. If false, the default, /// does just completed instances. /// </param> /// <param name="includeAllPackages"> /// If true, includes all packages with the returned results. The default is to only /// return the main installation data. /// </param> /// <returns> /// The list of installed instances. An empty list if none are installed. /// </returns> public static IList <VisualStudioInstance> GetInstalledInstances(int lcid = 0, Boolean includeIncompleteInstances = false, Boolean includeAllPackages = false) { List <VisualStudioInstance> resultList = new List <VisualStudioInstance>(); // Grab the config interface and enumerate the instances. var setupConfig = GetSetupConfig(); if (setupConfig != null) { IEnumSetupInstances instanceList = null; if (includeIncompleteInstances == false) { instanceList = setupConfig.EnumInstances(); } else { instanceList = setupConfig.EnumAllInstances(); } // Now it is time to loop! int fetched; ISetupInstance2[] instance = new ISetupInstance2[1]; do { instanceList.Next(1, instance, out fetched); if (fetched > 0) { var filledInstance = FillInInstanceData(instance[0], lcid, includeAllPackages); resultList.Add(filledInstance); } } while (fetched > 0); } return(resultList); }
private static List <ISetupInstance> GetVisualStudioInstances() { List <ISetupInstance> vsInstances = new(); try { SetupConfiguration setupConfiguration = new(); ISetupConfiguration2 setupConfiguration2 = setupConfiguration; IEnumSetupInstances setupInstances = setupConfiguration2.EnumInstances(); ISetupInstance[] instances = new ISetupInstance[1]; int fetched = 0; do { setupInstances.Next(1, instances, out fetched); if (fetched > 0) { ISetupInstance2 instance = (ISetupInstance2)instances[0]; // .NET Workloads only shipped in 17.0 and later and we should only look at IDE based SKUs // such as community, professional, and enterprise. if (Version.TryParse(instance.GetInstallationVersion(), out Version version) && version.Major >= 17 && s_visualStudioProducts.Contains(instance.GetProduct().GetId())) { vsInstances.Add(instances[0]); } } }while (fetched > 0); } catch (COMException e) when(e.ErrorCode == REGDB_E_CLASSNOTREG) { // Query API not registered, good indication there are no VS installations of 15.0 or later. // Other exceptions are passed through since that likely points to a real error. } return(vsInstances); }
static List <VisualStudioInstallation> GetVisualStudioInstallations() { CachedInstalls.Clear(); try { SetupConfiguration Setup = new SetupConfiguration(); IEnumSetupInstances Enumerator = Setup.EnumAllInstances(); ISetupInstance[] Instances = new ISetupInstance[1]; for (; ;) { int NumFetched; Enumerator.Next(1, Instances, out NumFetched); if (NumFetched == 0) { break; } ISetupInstance2 Instance = (ISetupInstance2)Instances[0]; if ((Instance.GetState() & InstanceState.Local) == InstanceState.Local) { string VersionString = Instance.GetInstallationVersion(); string[] Components = VersionString.Split('.'); if (Components.Length == 0) { continue; } int MajorVersion; string InstallationPath = Instance.GetInstallationPath(); string DevEnvPath = Path.Combine(InstallationPath, "Common7\\IDE\\devenv.exe"); if (!int.TryParse(Components[0], out MajorVersion) || (MajorVersion != 15 && MajorVersion != 16)) { continue; } if (!File.Exists(DevEnvPath)) { continue; } VisualStudioInstallation Installation = new VisualStudioInstallation() { BaseDir = InstallationPath, DevEnvPath = DevEnvPath, MajorVersion = MajorVersion, ROTMoniker = string.Format("!VisualStudio.DTE.{0}.0", MajorVersion) }; CachedInstalls.Add(Installation); } } } catch (Exception Ex) { MessageBox.Show(string.Format("Exception while finding Visual Studio installations {0}", Ex.Message)); } // prefer newer versions CachedInstalls.Sort((A, B) => { return(-A.MajorVersion.CompareTo(B.MajorVersion)); }); return(CachedInstalls); }
public static VisualStudioInstance GetVisualStudioInstance() { if (VisualStudioInstanceList == null) { VisualStudioInstanceList = new List <VisualStudioInstance>(); try { if (new SetupConfigurationClass() is ISetupConfiguration2 setupConfiguration) { IEnumSetupInstances instanceEnumerator = setupConfiguration.EnumAllInstances(); ISetupInstance2[] instances = new ISetupInstance2[3]; instanceEnumerator.Next(instances.Length, instances, out var instancesFetched); if (instancesFetched == 0) { return(null); } do { for (int i = 0; i < instancesFetched; i++) { VisualStudioInstanceList.Add(new VisualStudioInstance(instances[i])); } instanceEnumerator.Next(instances.Length, instances, out instancesFetched); }while (instancesFetched != 0); } } catch { } VisualStudioInstanceList.Sort((p1, p2) => { if (Version.TryParse(p1.InstallationVersion, out Version version1) && Version.TryParse(p2.InstallationVersion, out Version version2)) { if (version1 < version2) { return(1); } else if (version1 > version2) { return(-1); } return(version1.CompareTo(version2)); } return(1); }); } if (VisualStudioInstance == null) { foreach (VisualStudioInstance instance in VisualStudioInstanceList) { if (instance.HasRequiredDependency) { VisualStudioInstance = instance; break; } } } return(VisualStudioInstance); }
/// <summary> /// Gets the installed Visual Studio instances (the first item is the latest version). /// </summary> /// <returns>The install locations.</returns> public static IReadOnlyList <VisualStudioInstance> GetInstances() { if (_installDirs == null) { _installDirs = new List <VisualStudioInstance>(); if (Environment.OSVersion.Platform == PlatformID.Win32NT) { // Visual Studio 2017-2020 List <VisualStudioInstance> preReleaseInstallDirs = null; try { SetupConfiguration setup = new SetupConfiguration(); IEnumSetupInstances enumerator = setup.EnumAllInstances(); ISetupInstance[] instances = new ISetupInstance[1]; while (true) { enumerator.Next(1, instances, out int fetchedCount); if (fetchedCount == 0) { break; } ISetupInstance2 instance = (ISetupInstance2)instances[0]; if ((instance.GetState() & InstanceState.Local) == InstanceState.Local) { VisualStudioVersion version; string displayName = instance.GetDisplayName(); if (displayName.Contains("2019")) { version = VisualStudioVersion.VisualStudio2019; } else if (displayName.Contains("2017")) { version = VisualStudioVersion.VisualStudio2017; } else { throw new Exception(string.Format("Unknown Visual Studio installation. Display name: {0}", displayName)); } var vsInstance = new VisualStudioInstance { Version = version, Path = instance.GetInstallationPath(), }; if (instance is ISetupInstanceCatalog catalog && catalog.IsPrerelease()) { if (preReleaseInstallDirs == null) { preReleaseInstallDirs = new List <VisualStudioInstance>(); } preReleaseInstallDirs.Add(vsInstance); } else { _installDirs.Add(vsInstance); } } } }
/// <summary> /// Uses the VS SetupConfiguration COM API to resolve a path to a version-specific executable like DevEnv.exe or MSBuild.exe. /// </summary> /// <param name="buildVersionPath">Used to build a version-specific path to try to resolve.</param> /// <param name="minMajorVersion">The minimum major version to look for. This defaults to <see cref="VS2017MajorVersion"/>.</param> /// <param name="maxMajorVersion">The maximum major version to look for. This defaults to <see cref="int.MaxValue"/>.</param> /// <param name="resolvedPathMustExist">Whether the resolved version-specific path must exist. This defaults to false.</param> /// <returns>The resolved path for the highest matched version or null if no version was matched.</returns> public static string?ResolvePath( Func <Version, string> buildVersionPath, int minMajorVersion = VS2017MajorVersion, int maxMajorVersion = int.MaxValue, bool resolvedPathMustExist = false) { string? result = null; Version?resultVersion = null; // VS 2017 and up allow multiple side-by-side editions to be installed, and we have to use a COM API to enumerate the installed instances. // https://github.com/mluparu/vs-setup-samples - COM API samples // https://code.msdn.microsoft.com/Visual-Studio-Setup-0cedd331 - More Q&A about the COM API samples // https://blogs.msdn.microsoft.com/vcblog/2017/03/06/finding-the-visual-c-compiler-tools-in-visual-studio-2017/#comment-273625 // https://github.com/Microsoft/vswhere - A redistributable .exe for enumerating the VS instances from the command line. // https://blogs.msdn.microsoft.com/heaths/2016/09/15/changes-to-visual-studio-15-setup/ const int REGDB_E_CLASSNOTREG = -2147221164; // 0x80040154 try { // From MS example: https://github.com/Microsoft/vs-setup-samples/blob/master/Setup.Configuration.CS/Program.cs SetupConfiguration configuration = new(); IEnumSetupInstances instanceEnumerator = configuration.EnumAllInstances(); int fetched; ISetupInstance[] instances = new ISetupInstance[1]; do { instanceEnumerator.Next(1, instances, out fetched); if (fetched > 0) { ISetupInstance instance = instances[0]; if (instance != null && Version.TryParse(instance.GetInstallationVersion(), out Version? version) && version.Major >= minMajorVersion && version.Major <= maxMajorVersion) { InstanceState state = ((ISetupInstance2)instance).GetState(); if (state == InstanceState.Complete) { string?versionPath = buildVersionPath?.Invoke(version); if (!string.IsNullOrEmpty(versionPath)) { string resolvedPath = instance.ResolvePath(versionPath); if ((resultVersion == null || resultVersion < version) && (!resolvedPathMustExist || File.Exists(resolvedPath) || Directory.Exists(resolvedPath))) { result = resolvedPath; resultVersion = version; // If we're looking for a single version, then we don't need to keep looking. if (minMajorVersion == maxMajorVersion) { break; } } } } } } }while (fetched > 0); } #pragma warning disable CC0004 // Catch block cannot be empty catch (COMException ex) when(ex.HResult == REGDB_E_CLASSNOTREG) { // The SetupConfiguration API is not registered, so assume no instances are installed. } catch (Exception) { // Heath Stewart (MSFT), the author of the SetupConfiguration API, says to treat any exception as "no instances installed." // https://code.msdn.microsoft.com/windowsdesktop/Visual-Studio-Setup-0cedd331/view/Discussions#content } #pragma warning restore CC0004 // Catch block cannot be empty return(result); }