public void Search(RegistryKey root, InterpreterArchitecture assumedArch)
        {
            if (root == null)
            {
                return;
            }

            var companies = GetSubkeys(root);

            foreach (var company in companies)
            {
                if ("PyLauncher".Equals(company, StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }
                bool pythonCore = "PythonCore".Equals(company, StringComparison.OrdinalIgnoreCase);

                using (var companyKey = root.OpenSubKey(company)) {
                    if (companyKey == null)
                    {
                        continue;
                    }

                    var companyDisplay    = companyKey.GetValue("DisplayName") as string;
                    var companySupportUrl = companyKey.GetValue("SupportUrl") as string;

                    if (pythonCore)
                    {
                        companyDisplay    = companyDisplay ?? PythonCoreCompanyDisplayName;
                        companySupportUrl = companySupportUrl ?? PythonCoreSupportUrl;
                    }
                    else
                    {
                        companyDisplay = companyDisplay ?? company;
                    }

                    var tags = GetSubkeys(companyKey);
                    foreach (var tag in tags)
                    {
                        using (var tagKey = companyKey.OpenSubKey(tag))
                            using (var installKey = tagKey?.OpenSubKey("InstallPath")) {
                                var config = TryReadConfiguration(company, tag, tagKey, installKey, pythonCore, assumedArch);
                                if (config == null)
                                {
                                    continue;
                                }

                                if (_seenIds.Add(config.Id))
                                {
                                    var supportUrl = tagKey.GetValue("SupportUrl") as string ?? companySupportUrl;

                                    var info = new PythonInterpreterInformation(config, companyDisplay, companySupportUrl, supportUrl);
                                    _info.Add(info);
                                }
                            }
                    }
                }
            }
        }
 /// <summary>
 /// <para>Constructs a new interpreter configuration based on the
 /// provided values.</para>
 /// <para>No validation is performed on the parameters.</para>
 /// <para>If winPath is null or empty,
 /// <see cref="WindowsInterpreterPath"/> will be set to path.</para>
 /// </summary>
 public InterpreterConfiguration(
     string id,
     string description,
     string prefixPath            = null,
     string path                  = null,
     string winPath               = "",
     string pathVar               = "",
     InterpreterArchitecture arch = default(InterpreterArchitecture),
     Version version              = null
     )
 {
     Id                      = id;
     Description             = description;
     PrefixPath              = prefixPath;
     InterpreterPath         = path;
     WindowsInterpreterPath  = string.IsNullOrEmpty(winPath) ? path : winPath;
     PathEnvironmentVariable = pathVar;
     Architecture            = arch ?? InterpreterArchitecture.Unknown;
     Version                 = version ?? new Version();
 }
        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(arch, version);
                }
                else
                {
                    description = "{0} {1}".FormatUI(company, tag);
                }
            }

            return(new InterpreterConfiguration(
                       id,
                       description,
                       prefixPath,
                       exePath,
                       exewPath,
                       CPythonInterpreterFactoryConstants.PathEnvironmentVariableName,
                       arch,
                       sysVersion
                       ));
        }
Example #4
0
        public void Search(RegistryKey root, InterpreterArchitecture assumedArch)
        {
            if (root == null)
            {
                return;
            }

            var companies = GetSubkeys(root);

            if (companies == null)
            {
                return;
            }

            foreach (var company in companies)
            {
                if ("PyLauncher".Equals(company, StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }
                bool pythonCore = PythonCoreCompany.Equals(company, StringComparison.OrdinalIgnoreCase);

                using (var companyKey = root.OpenSubKey(company)) {
                    if (companyKey == null)
                    {
                        continue;
                    }

                    var companyDisplay    = companyKey.GetValue("DisplayName") as string;
                    var companySupportUrl = companyKey.GetValue("SupportUrl") as string;

                    if (pythonCore)
                    {
                        companyDisplay    = companyDisplay ?? PythonCoreCompanyDisplayName;
                        companySupportUrl = companySupportUrl ?? PythonCoreSupportUrl;
                    }
                    else
                    {
                        companyDisplay = companyDisplay ?? company;
                    }

                    var tags = GetSubkeys(companyKey);
                    if (tags == null)
                    {
                        continue;
                    }
                    foreach (var tag in tags)
                    {
                        using (var tagKey = companyKey.OpenSubKey(tag))
                            using (var installKey = tagKey?.OpenSubKey("InstallPath")) {
                                var config = TryReadConfiguration(company, tag, tagKey, installKey, pythonCore, assumedArch);
                                if (config == null)
                                {
                                    continue;
                                }

                                if (_seenIds.Add(config.Id))
                                {
                                    var supportUrl = tagKey.GetValue("SupportUrl") as string ?? companySupportUrl;

                                    // We don't want to send people to http://python.org, even
                                    // if that's what is in the registry, so catch and fix it.
                                    if (!string.IsNullOrEmpty(supportUrl))
                                    {
                                        var url = supportUrl.TrimEnd('/');
                                        if (url.Equals("http://www.python.org", StringComparison.OrdinalIgnoreCase) ||
                                            url.Equals("http://python.org", StringComparison.OrdinalIgnoreCase))
                                        {
                                            supportUrl = PythonCoreSupportUrl;
                                        }
                                    }

                                    var info = new PythonInterpreterInformation(config, companyDisplay, companySupportUrl, supportUrl);
                                    _info.Add(info);
                                }
                            }
                    }
                }
            }
        }