public string AddConfigurableInterpreter(string name, InterpreterConfiguration config) { var collection = PythonInterpreterKey + "\\" + name; using (var key = Registry.CurrentUser.CreateSubKey(collection, true)) { key.SetValue(LibraryPathKey, config.LibraryPath ?? string.Empty); key.SetValue(ArchitectureKey, config.ArchitectureString); key.SetValue(VersionKey, config.Version.ToString()); key.SetValue(PathEnvVarKey, config.PathEnvironmentVariable ?? string.Empty); key.SetValue(DescriptionKey, config.Description ?? string.Empty); using (var installPath = key.CreateSubKey("InstallPath")) { string exePath = config.InterpreterPath ?? config.WindowsInterpreterPath ?? ""; if (!String.IsNullOrWhiteSpace(exePath)) { installPath.SetValue("", Path.GetDirectoryName(exePath)); } installPath.SetValue(WindowsPathKey, config.WindowsInterpreterPath ?? string.Empty); installPath.SetValue(PathKey, config.InterpreterPath ?? string.Empty); } } // ensure we're up to date... _cpythonProvider.Value.DiscoverInterpreterFactories(); return(CPythonInterpreterFactoryConstants.GetIntepreterId( "VisualStudio", config.Architecture, name )); }
public bool IsConfigurable(string id) { string company, tag; return(CPythonInterpreterFactoryConstants.TryParseInterpreterId(id, out company, out tag) && company == CustomCompany); }
public string AddConfigurableInterpreter(string name, InterpreterConfiguration config) { using (_cpythonProvider.Value.SuppressDiscoverFactories()) { var collection = CustomInterpreterKey + "\\" + name; using (var key = Registry.CurrentUser.CreateSubKey(CustomInterpreterKey, true)) { key.SetValue(DescriptionKey, Strings.CustomEnvironmentLabel); } using (var key = Registry.CurrentUser.CreateSubKey(collection, true)) { if (config.Architecture != InterpreterArchitecture.Unknown) { key.SetValue(ArchitectureKey, config.Architecture.ToPEP514()); } else { key.DeleteValue(ArchitectureKey, false); } if (config.Version != new Version()) { key.SetValue(VersionKey, config.Version.ToString()); } else { key.DeleteValue(VersionKey, false); } if (!string.IsNullOrEmpty(config.PathEnvironmentVariable)) { key.SetValue(PathEnvVarKey, config.PathEnvironmentVariable); } else { key.DeleteValue(PathEnvVarKey, false); } if (!string.IsNullOrEmpty(config.Description)) { key.SetValue(DescriptionKey, config.Description); } else { key.DeleteValue(DescriptionKey, false); } using (var installPath = key.CreateSubKey("InstallPath")) { string exePath = config.InterpreterPath ?? config.WindowsInterpreterPath ?? ""; if (!string.IsNullOrEmpty(config.PrefixPath)) { installPath.SetValue("", config.PrefixPath); } else if (!string.IsNullOrWhiteSpace(exePath)) { installPath.SetValue("", Path.GetDirectoryName(exePath)); } installPath.SetValue(WindowsPathKey, config.WindowsInterpreterPath ?? string.Empty); installPath.SetValue(PathKey, config.InterpreterPath ?? string.Empty); } } } return(CPythonInterpreterFactoryConstants.GetInterpreterId(CustomCompany, name)); }
public void RemoveConfigurableInterpreter(string id) { string company, tag; if (CPythonInterpreterFactoryConstants.TryParseInterpreterId(id, out company, out tag) && company == CustomCompany) { var collection = CustomInterpreterKey + "\\" + tag; try { Registry.CurrentUser.DeleteSubKeyTree(collection); _cpythonProvider.Value.DiscoverInterpreterFactories(); } catch (ArgumentException) { } } }
private InterpreterConfiguration TryReadConfiguration( string company, string tag, RegistryKey tagKey, RegistryKey installKey, bool pythonCoreCompatibility, InterpreterArchitecture assumedArch ) { if (tagKey == null || installKey == null) { return(null); } var prefixPath = installKey.GetValue(null) as string; var exePath = installKey.GetValue("ExecutablePath") as string; var exewPath = installKey.GetValue("WindowedExecutablePath") as string; if (pythonCoreCompatibility && !string.IsNullOrEmpty(prefixPath)) { if (string.IsNullOrEmpty(exePath)) { exePath = PathUtils.GetAbsoluteFilePath(prefixPath, CPythonInterpreterFactoryConstants.ConsoleExecutable); } if (string.IsNullOrEmpty(exewPath)) { exewPath = PathUtils.GetAbsoluteFilePath(prefixPath, CPythonInterpreterFactoryConstants.WindowsExecutable); } } var version = tagKey.GetValue("Version") as string; if (pythonCoreCompatibility && string.IsNullOrEmpty(version) && tag.Length >= 3) { version = tag.Substring(0, 3); } Version sysVersion; var sysVersionString = tagKey.GetValue("SysVersion") as string; if (pythonCoreCompatibility && string.IsNullOrEmpty(sysVersionString) && tag.Length >= 3) { sysVersionString = tag.Substring(0, 3); } if (string.IsNullOrEmpty(sysVersionString) || !Version.TryParse(sysVersionString, out sysVersion)) { sysVersion = new Version(0, 0); } PythonLanguageVersion langVersion; try { langVersion = sysVersion.ToLanguageVersion(); } catch (InvalidOperationException) { langVersion = PythonLanguageVersion.None; sysVersion = new Version(0, 0); } InterpreterArchitecture arch; if (!InterpreterArchitecture.TryParse(tagKey.GetValue("SysArchitecture", null) as string, out arch)) { arch = assumedArch; } if (arch == InterpreterArchitecture.Unknown && File.Exists(exePath)) { switch (NativeMethods.GetBinaryType(exePath)) { case System.Reflection.ProcessorArchitecture.X86: arch = InterpreterArchitecture.x86; break; case System.Reflection.ProcessorArchitecture.Amd64: arch = InterpreterArchitecture.x64; break; } } if (pythonCoreCompatibility && sysVersion != null && sysVersion < new Version(3, 5) && arch == InterpreterArchitecture.x86) { // Older versions of CPython did not include // "-32" in their Tag, so we will add it here // for uniqueness. tag += "-32"; } var id = CPythonInterpreterFactoryConstants.GetInterpreterId(company, tag); var description = tagKey.GetValue("DisplayName") as string; if (string.IsNullOrEmpty(description)) { if (pythonCoreCompatibility) { description = "Python {0}{1: ()}".FormatUI(version, arch); } else { description = "{0} {1}".FormatUI(company, tag); } } return(new InterpreterConfiguration( id, description, prefixPath, exePath, exewPath, CPythonInterpreterFactoryConstants.PathEnvironmentVariableName, arch, sysVersion )); }
private bool TryRegisterInterpreter(HashSet <string> registeredPaths, HashSet <string> registeredIds, bool ignoreRegisteredPaths, RegistryKey vendorKey, string key, ProcessorArchitecture?arch) { Version version = null; ProcessorArchitecture?arch2 = null; using (var interpKey = vendorKey.OpenSubKey(key)) { if (interpKey == null) { // the key unexpectedly disappeared return(false); } string id = key; var versionValue = interpKey.GetValue("SysVersion") as string; if ((versionValue == null || !Version.TryParse(versionValue, out version)) && !TryParsePythonVersion(key, out version, out arch2, ref id)) { version = new Version(2, 7); } var archStr = interpKey.GetValue("Architecture") as string; switch (archStr) { case "x64": arch = ProcessorArchitecture.Amd64; break; case "x86": arch = ProcessorArchitecture.X86; break; } if (version.Major == 2 && version.Minor <= 4) { // 2.4 and below not supported. return(false); } var installPath = vendorKey.OpenSubKey(key + "\\InstallPath"); if (installPath != null) { var basePathObj = installPath.GetValue(""); if (basePathObj == null) { // http://pytools.codeplex.com/discussions/301384 // messed up install, we don't know where it lives, we can't use it. return(false); } string basePath = basePathObj.ToString(); if (!PathUtils.IsValidPath(basePath)) { // Invalid path in registry return(false); } if (!registeredPaths.Add(basePath) && !ignoreRegisteredPaths) { // registered in both HCKU and HKLM (we allow duplicate paths in HKCU // which is why we have ignoreRegisteredPaths) return(false); } var actualArch = arch ?? arch2; if (!actualArch.HasValue) { actualArch = NativeMethods.GetBinaryType(Path.Combine(basePath, CPythonInterpreterFactoryConstants.ConsoleExecutable)); } string description = interpKey.GetValue("Description") as string; if (description == null) { description = "Python"; } string newId = CPythonInterpreterFactoryConstants.GetIntepreterId(GetVendorName(vendorKey), actualArch, id); InterpreterInformation existing; lock (_factories) { _factories.TryGetValue(newId, out existing); try { var interpPath = installPath.GetValue("ExecutablePath") as string ?? Path.Combine(basePath, CPythonInterpreterFactoryConstants.ConsoleExecutable); var windowsPath = installPath.GetValue("WindowedExecutablePath") as string ?? Path.Combine(basePath, CPythonInterpreterFactoryConstants.WindowsExecutable); var libraryPath = Path.Combine(basePath, CPythonInterpreterFactoryConstants.LibrarySubPath); string prefixPath = Path.GetDirectoryName(interpPath); registeredIds.Add(newId); var newConfig = new InterpreterConfiguration( newId, description, prefixPath, interpPath, windowsPath, libraryPath, CPythonInterpreterFactoryConstants.PathEnvironmentVariableName, actualArch ?? ProcessorArchitecture.None, version ); if (existing == null || !newConfig.Equals(existing.Configuration)) { _factories[newId] = new InterpreterInformation(newConfig); return(true); } } catch (ArgumentException) { } } return(false); } } return(false); }
private VisualStudioInterpreterConfiguration TryReadConfiguration( string company, string tag, RegistryKey tagKey, RegistryKey installKey, bool pythonCoreCompatibility, InterpreterArchitecture assumedArch ) { if (tagKey == null || installKey == null) { return(null); } string prefixPath, exePath, exewPath; try { prefixPath = PathUtils.NormalizePath(installKey.GetValue(null) as string); exePath = PathUtils.NormalizePath(installKey.GetValue("ExecutablePath") as string); exewPath = PathUtils.NormalizePath(installKey.GetValue("WindowedExecutablePath") as string); } catch (ArgumentException ex) { Debug.Fail(ex.ToUnhandledExceptionMessage(GetType())); return(null); } if (pythonCoreCompatibility && !string.IsNullOrEmpty(prefixPath)) { if (string.IsNullOrEmpty(exePath)) { try { exePath = PathUtils.GetAbsoluteFilePath(prefixPath, CPythonInterpreterFactoryConstants.ConsoleExecutable); } catch (ArgumentException) { } } if (string.IsNullOrEmpty(exewPath)) { try { exewPath = PathUtils.GetAbsoluteFilePath(prefixPath, CPythonInterpreterFactoryConstants.WindowsExecutable); } catch (ArgumentException) { } } } var version = tagKey.GetValue("Version") as string; if (pythonCoreCompatibility && string.IsNullOrEmpty(version) && tag.Length >= 3) { version = tag.Substring(0, 3); } var sysVersionString = tagKey.GetValue("SysVersion") as string; if (pythonCoreCompatibility && string.IsNullOrEmpty(sysVersionString) && tag.Length >= 3) { sysVersionString = tag.Substring(0, 3); } if (string.IsNullOrEmpty(sysVersionString) || !Version.TryParse(sysVersionString, out var sysVersion)) { sysVersion = new Version(0, 0); } if (sysVersion < new Version(3, 0)) { return(null); // Python 2.x is no longer supported. } try { sysVersion.ToLanguageVersion(); } catch (InvalidOperationException) { sysVersion = new Version(0, 0); } if (!InterpreterArchitecture.TryParse(tagKey.GetValue("SysArchitecture", null) as string, out var arch)) { arch = assumedArch; } if (arch == InterpreterArchitecture.Unknown && File.Exists(exePath)) { switch (NativeMethods.GetBinaryType(exePath)) { case System.Reflection.ProcessorArchitecture.X86: arch = InterpreterArchitecture.x86; break; case System.Reflection.ProcessorArchitecture.Amd64: arch = InterpreterArchitecture.x64; break; } } if (pythonCoreCompatibility && sysVersion != null && sysVersion < new Version(3, 5) && arch == InterpreterArchitecture.x86) { // Older versions of CPython did not include // "-32" in their Tag, so we will add it here // for uniqueness. tag += "-32"; } var pathVar = tagKey.GetValue("PathEnvironmentVariable") as string ?? CPythonInterpreterFactoryConstants.PathEnvironmentVariableName; var id = CPythonInterpreterFactoryConstants.GetInterpreterId(company, tag); var description = tagKey.GetValue("DisplayName") as string; if (string.IsNullOrEmpty(description)) { description = pythonCoreCompatibility ? "Python {0}{1: ()}".FormatUI(version, arch) : "{0} {1}".FormatUI(company, tag); } return(new VisualStudioInterpreterConfiguration( id, description, prefixPath, exePath, exewPath, pathVar, arch, sysVersion )); }