private static IEnumerable <string> CollectUniversalCRuntimeIncludeDirs( string vsDir, ToolchainVersion windowsKitSdk, int windowsSdkMajorVer) { var includes = new List <string>(); // Check vsvars32.bat to see location of the new Universal C runtime library. string ucrtPaths = string.Empty; var vsVarsPath = Path.Combine(vsDir, @"Common7\Tools\vsvars32.bat"); if (File.Exists(vsVarsPath)) { var vsVarsFile = File.ReadAllText(vsVarsPath); var match = Regex.Match(vsVarsFile, @"INCLUDE=%UniversalCRTSdkDir%(.+)%INCLUDE%"); if (match.Success) { ucrtPaths = match.Groups[1].Value; } } if (string.IsNullOrWhiteSpace(ucrtPaths)) { return(includes); } // like the rest of GetSystemIncludes, this is a hack // which copies the logic in the vcvarsqueryregistry.bat // the correct way would be to execute the script and collect the values // there's a reference implementation in the 'get_MSVC_UCRTVersion_from_VS_batch_script' branch // however, it cannot be used because it needs invoking an external process to run the .bat // which is killed prematurely by VS when the pre-build events of wrapper projects are run const string ucrtVersionEnvVar = "%UCRTVersion%"; foreach (var splitPath in ucrtPaths.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) { var path = splitPath.TrimStart('\\'); var index = path.IndexOf(ucrtVersionEnvVar, StringComparison.Ordinal); if (index >= 0) { var include = path.Substring(0, index); var parentIncludeDir = Path.Combine(windowsKitSdk.Directory, include); var dirPrefix = windowsSdkMajorVer + "."; var includeDir = (from dir in Directory.EnumerateDirectories(parentIncludeDir).OrderByDescending(d => d) where Path.GetFileName(dir).StartsWith(dirPrefix) select Path.Combine(windowsKitSdk.Directory, include, dir)).FirstOrDefault(); if (!string.IsNullOrEmpty(includeDir)) { includes.Add(Path.Combine(includeDir, Path.GetFileName(path))); } } else { includes.Add(Path.Combine(windowsKitSdk.Directory, path)); } } return(includes); }
/// <summary> /// Read registry strings looking for matching values. /// </summary> /// <param name="keyPath">The path to the key in the registry.</param> /// <param name="matchValue">The value to match in the located key, if any.</param> /// <param name="view">The type of registry, 32 or 64, to target.</param> /// public static List <ToolchainVersion> GetToolchainsFromSystemRegistryValues( string keyPath, string matchValue, RegistryView view) { string subKey; var hive = GetRegistryHive(keyPath, out subKey); using (var rootKey = RegistryKey.OpenBaseKey(hive, view)) using (var key = rootKey.OpenSubKey(subKey, writable: false)) { var entries = new List <ToolchainVersion>(); if (key == null) { return(entries); } foreach (var valueName in key.GetValueNames()) { if (!valueName.Contains(matchValue)) { continue; } var value = key.GetValue(valueName) as string; if (value == null) { continue; } float version = 0; // Get the number version from the key value. var match = Regex.Match(value, @".*([1-9][0-9]*\.?[0-9]*)"); if (match.Success) { float.TryParse(match.Groups[1].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out version); } var entry = new ToolchainVersion { Directory = value, Version = version, Value = valueName }; entries.Add(entry); } return(entries); } }
static bool HandleToolchainRegistrySubKey(out ToolchainVersion entry, RegistryKey key, string valueName, string subKeyName) { entry = new ToolchainVersion(); // Get the number version from the key. var match = Regex.Match(subKeyName, @"[1-9][0-9]*\.?[0-9]*"); if (!match.Success) { return(false); } var versionText = match.Groups[0].Value; float version; float.TryParse(versionText, NumberStyles.Number, CultureInfo.InvariantCulture, out version); using (var versionKey = key.OpenSubKey(subKeyName)) { if (versionKey == null) { return(false); } // Check that the key has a value passed by the caller. var keyValue = versionKey.GetValue(valueName); if (keyValue == null) { return(false); } entry = new ToolchainVersion { Version = version, Directory = keyValue.ToString() }; } return(true); }
/// <summary> /// Tries to get all vs 2017 instances. /// </summary> /// <param name="versions">Collection holding available visual studio instances</param> /// <returns>Success of the operation</returns> private static bool GetVs2017Instances(ICollection <ToolchainVersion> versions) { const int REGDB_E_CLASSNOTREG = unchecked ((int)0x80040154); try { var query = new SetupConfiguration(); var query2 = (ISetupConfiguration2)query; var e = query2.EnumAllInstances(); int fetched; var instances = new ISetupInstance[1]; do { e.Next(1, instances, out fetched); if (fetched > 0) { var instance = (ISetupInstance2)instances[0]; var packages = instance.GetPackages(); var toolchain = new ToolchainVersion { Directory = instance.GetInstallationPath() + @"\Common7\IDE", Version = Single.Parse(instance.GetInstallationVersion().Remove(2)), Value = null // Not used currently }; versions.Add(toolchain); } }while (fetched > 0); } catch (COMException ex) when(ex.HResult == REGDB_E_CLASSNOTREG) { Console.WriteLine("The query API is not registered. Assuming no instances are installed."); return(false); } catch (Exception ex) { Console.Error.WriteLine($"Error 0x{ex.HResult:x8}: {ex.Message}"); return(false); } return(true); }
static bool HandleToolchainRegistrySubKey(out ToolchainVersion entry, RegistryKey key, string valueName, string subKeyName) { entry = new ToolchainVersion(); // Get the number version from the key. var match = Regex.Match(subKeyName, @"[1-9][0-9]*\.?[0-9]*"); if (!match.Success) return false; var versionText = match.Groups[0].Value; float version; float.TryParse(versionText, NumberStyles.Number, CultureInfo.InvariantCulture, out version); using (var versionKey = key.OpenSubKey(subKeyName)) { if (versionKey == null) return false; // Check that the key has a value passed by the caller. var keyValue = versionKey.GetValue(valueName); if (keyValue == null) return false; entry = new ToolchainVersion { Version = version, Directory = keyValue.ToString() }; } return true; }
/// Read registry strings looking for matching values. public static bool GetToolchainsFromSystemRegistryValues(string keyPath, string matchValue, ICollection<ToolchainVersion> entries, RegistryView view) { string subKey; var hive = GetRegistryHive(keyPath, out subKey); using (var rootKey = RegistryKey.OpenBaseKey(hive, view)) using (var key = rootKey.OpenSubKey(subKey, writable: false)) { if (key == null) return false; foreach (var valueName in key.GetValueNames()) { if (!valueName.Contains(matchValue)) continue; var value = key.GetValue(valueName) as string; if (value == null) continue; float version = 0; // Get the number version from the key value. var match = Regex.Match(value, @".*([1-9][0-9]*\.?[0-9]*)"); if (match.Success) { float.TryParse(match.Groups[1].Value, NumberStyles.Number, CultureInfo.InvariantCulture, out version); } var entry = new ToolchainVersion { Directory = value, Version = version, Value = valueName }; entries.Add(entry); } } return true; }
private static IEnumerable<string> CollectUniversalCRuntimeIncludeDirs( string vsDir, ToolchainVersion windowsKitSdk, int windowsSdkMajorVer) { var includes = new List<string>(); // Check vsvars32.bat to see location of the new Universal C runtime library. string ucrtPaths = string.Empty; var vsVarsPath = Path.Combine(vsDir, @"Common7\Tools\vsvars32.bat"); if (File.Exists(vsVarsPath)) { var vsVarsFile = File.ReadAllText(vsVarsPath); var match = Regex.Match(vsVarsFile, @"INCLUDE=%UniversalCRTSdkDir%(.+)%INCLUDE%"); if (match.Success) ucrtPaths = match.Groups[1].Value; } if (string.IsNullOrWhiteSpace(ucrtPaths)) return includes; // like the rest of GetSystemIncludes, this is a hack // which copies the logic in the vcvarsqueryregistry.bat // the correct way would be to execute the script and collect the values // there's a reference implementation in the 'get_MSVC_UCRTVersion_from_VS_batch_script' branch // however, it cannot be used because it needs invoking an external process to run the .bat // which is killed prematurely by VS when the pre-build events of wrapper projects are run const string ucrtVersionEnvVar = "%UCRTVersion%"; foreach (var splitPath in ucrtPaths.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries)) { var path = splitPath.TrimStart('\\'); var index = path.IndexOf(ucrtVersionEnvVar, StringComparison.Ordinal); if (index >= 0) { var include = path.Substring(0, index); var parentIncludeDir = Path.Combine(windowsKitSdk.Directory, include); var dirPrefix = windowsSdkMajorVer + "."; var includeDir = (from dir in Directory.EnumerateDirectories(parentIncludeDir).OrderByDescending(d => d) where Path.GetFileName(dir).StartsWith(dirPrefix) select Path.Combine(windowsKitSdk.Directory, include, dir)).FirstOrDefault(); if (!string.IsNullOrEmpty(includeDir)) includes.Add(Path.Combine(includeDir, Path.GetFileName(path))); } else includes.Add(Path.Combine(windowsKitSdk.Directory, path)); } return includes; }