public Uninstaller() { var displayNameRegex = new Regex(@"^(Microsoft )?\.NET Core SDK (?<version>\d+\.\d+\.\d+(-.*)?) \((?<arch>x(64|86))\)$"); //TODO: figure out how to query Windows Installer. //WMI could work, but it is so slow. using (var hive = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32)) { using (var uninstallKey = hive.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall")) { foreach (var productKeyName in uninstallKey.GetSubKeyNames()) { Guid productCode; if (!Guid.TryParseExact(productKeyName, "B", out productCode)) { continue; } using (var productKey = uninstallKey.OpenSubKey(productKeyName)) { string displayName = productKey.GetValue("DisplayName") as string; if (displayName == null) { continue; } var match = displayNameRegex.Match(displayName); if (!match.Success) { continue; } var quietUninstallString = productKey.GetValue("QuietUninstallString") as string; if (quietUninstallString == null) { continue; } string arch = match.Groups["arch"].Value; string version = match.Groups["version"].Value; var sdkVersion = SdkVersion.Parse(version); if (arch == "x64") { x64UninstallComannds.Add(sdkVersion, quietUninstallString); } else if (arch == "x86") { x86UninstallCommands.Add(sdkVersion, quietUninstallString); } else { throw new Exception($"Unexpected architecture: '{displayName}'. Key: {productKey.Name}"); } } } } } }
private static void GetDotNetCoreSdksFromInstance(HashSet <SdkVersion> ret, string instancePath) { Catalog catalog; using (var fs = File.OpenRead(Path.Combine(instancePath, "catalog.json"))) { var dataSer = new DataContractJsonSerializer(typeof(Catalog)); catalog = (Catalog)dataSer.ReadObject(fs); } foreach (var pack in catalog.Packages) { if (!pack.ID.StartsWith("Microsoft.Net.Core.SDK.")) { continue; } if (pack.DetectConditions == null) { continue; } if (pack.DetectConditions.Expression != "CliX64RegKey" && pack.DetectConditions.Expression != "CliX86RegKey") { continue; } if (pack.DetectConditions.Conditions.Length != 1) { throw new Exception("Unexpected number of conditions on " + pack.ID); } var cond = pack.DetectConditions.Conditions[0]; var key = cond.RegistryKey; if (!key.StartsWith(@"HKEY_LOCAL_MACHINE\SOFTWARE\")) { continue; } if (!key.EndsWith(@"\dotnet\Setup\InstalledVersions\x64\sdk") && !key.EndsWith(@"\dotnet\Setup\InstalledVersions\x86\sdk")) { continue; } if (cond.RegistryType != "Integer") { throw new Exception("Unexpected 'registryType' for " + pack.ID); } if (cond.RegistryData != "1") { throw new Exception("Unexpected 'registryData' for " + pack.ID); } var ver = cond.RegistryValue; ret.Add(SdkVersion.Parse(ver)); } }
static void GetInstalledFromFileSystem(HashSet <DotNetCoreSdk> ret, bool is64Bit) { if (is64Bit && !Environment.Is64BitOperatingSystem) { return; } string progFilesEnvVar; if (!is64Bit && Environment.Is64BitOperatingSystem) { progFilesEnvVar = "ProgramFiles(x86)"; } else { progFilesEnvVar = "ProgramFiles"; } string progFiles = Environment.GetEnvironmentVariable(progFilesEnvVar); if (string.IsNullOrEmpty(progFiles) || !Directory.Exists(progFiles)) { throw new Exception("Could not find Program Files from environmental variable: " + progFilesEnvVar); } string dotnetSdksFolder = Path.Combine(progFiles, "dotnet", "sdk"); if (!Directory.Exists(dotnetSdksFolder)) { //assume there are no versions installed if the folder does not exist return; } foreach (var di in new DirectoryInfo(dotnetSdksFolder).GetDirectories()) { //assume nuget fallback folder if (!char.IsNumber(di.Name[0])) { continue; } ret.Add(new DotNetCoreSdk(is64Bit, SdkVersion.Parse(di.Name))); } }
static void GetInstalledFromRegistry(HashSet <DotNetCoreSdk> ret, RegistryKey hive, bool is64Bit) { const string REGISTRY_KEY_PATH = @"SOFTWARE\dotnet\Setup\InstalledVersions\{0}\sdk"; string path = string.Format(REGISTRY_KEY_PATH, is64Bit ? "x64" : "x86"); using (var key = hive.OpenSubKey(path, false)) { if (key == null) { //no versions installed return; } foreach (var sdkVersionString in key.GetValueNames()) { ret.Add(new DotNetCoreSdk(is64Bit, SdkVersion.Parse(sdkVersionString))); } } }
public DotNetCoreSdk(bool is64Bit, SdkVersion version) { Is64Bit = is64Bit; Version = version; }