Python 在Windows上的註冊表

爲什麼要設置註冊表項

目的是爲了其他工具找到註冊的Python信息,可執行文件位置,庫目錄等信息。

標準

PEP-0514: https://www.python.org/dev/peps/pep-0514/

註冊表位置

HKEY_CURRENT_USER\Software\Python\<Company>\<Tag>
HKEY_LOCAL_MACHINE\Software\Python\<Company>\<Tag>
HKEY_LOCAL_MACHINE\Software\Wow6432Node\Python\<Company>\<Tag>
  • Company: 公司名,官方Python用'PythonCore',Anaconda使用'ContinuumAnalytics'。‘PyLauncher’ 爲保留字段,PEP 397 launcher (py.exe).
  • <Tag>: 標籤,比如官方Python用版本號,也就是‘sys.winver’的輸出, Anaconda使用'Anaconda71-64‘
  • Wow6432Node下的是在64bit系統上爲兼容32bit程序訪問而使用的。
  • Company例子
HKEY_CURRENT_USER\Software\Python\ExampleCorp
    (Default) = (value not set)
    DisplayName = "Example Corp"
    SupportUrl = "http://www.example.com"
  • <Tag>下的例子
HKEY_CURRENT_USER\Software\Python\ExampleCorp\examplepy
    (Default) = (value not set)
    DisplayName = "Example Py Distro 3"
    SupportUrl = "http://www.example.com/distro-3"
    Version = "3.0.12345.0"
    SysVersion = "3.6.0"
    SysArchitecture = "64bit"
  • InstallPath的例子
HKEY_CURRENT_USER\Software\Python\ExampleCorp\examplepy\InstallPath
    (Default) = "C:\ExampleDistro30"
    ExecutablePath = "C:\ExampleDistro30\ex_python.exe"
    ExecutableArguments = "--arg1"
    WindowedExecutablePath = "C:\ExampleDistro30\ex_pythonw.exe"
    WindowedExecutableArguments = "--arg1"
  • Help下面的例子
HKEY_CURRENT_USER\Software\Python\ExampleCorp\6C465E66\Help
    Python\
        (Default) = "C:\ExampleDistro30\python36.chm"
        DisplayName = "Python Documentation"
    Extras\
        (Default) = "http://www.example.com/tutorial"
        DisplayName = "Example Distro Online Tutorial"
  • 完整的註冊表例子
HKEY_CURRENT_USER\Software\Python\PythonCore
    (Default) = (value not set)
    DisplayName = "Python Software Foundation"
    SupportUrl = "http://www.python.org/"

HKEY_CURRENT_USER\Software\Python\PythonCore\3.6
    (Default) = (value not set)
    DisplayName = "Python 3.6 (64-bit)"
    SupportUrl = "http://www.python.org/"
    Version = "3.6.0"
    SysVersion = "3.6"
    SysArchitecture = "64bit"

HKEY_CURRENT_USER\Software\Python\PythonCore\3.6\Help\Main Python Documentation
    (Default) = "C:\Users\Me\AppData\Local\Programs\Python\Python36\Doc\python360.chm"
    DisplayName = "Python 3.6.0 Documentation"

HKEY_CURRENT_USER\Software\Python\PythonCore\3.6\InstallPath
    (Default) = "C:\Users\Me\AppData\Local\Programs\Python\Python36\"
    ExecutablePath = "C:\Users\Me\AppData\Local\Programs\Python\Python36\python.exe"
    WindowedExecutablePath = "C:\Users\Me\AppData\Local\Programs\Python\Python36\pythonw.exe"
  • 枚舉系統中註冊的Python
# Display most-preferred environments.
# Assumes a 64-bit operating system
# Does not correctly handle PythonCore compatibility

import winreg

def enum_keys(key):
    i = 0
    while True:
        try:
            yield winreg.EnumKey(key, i)
        except OSError:
            break
        i += 1

def get_value(key, value_name):
    try:
        return winreg.QueryValue(key, value_name)
    except FileNotFoundError:
        return None

seen = set()
for hive, key, flags in [
    (winreg.HKEY_CURRENT_USER, r'Software\Python', 0),
    (winreg.HKEY_LOCAL_MACHINE, r'Software\Python', winreg.KEY_WOW64_64KEY),
    (winreg.HKEY_LOCAL_MACHINE, r'Software\Python', winreg.KEY_WOW64_32KEY),
]:
    with winreg.OpenKeyEx(hive, key, access=winreg.KEY_READ | flags) as root_key:
        for company in enum_keys(root_key):
            if company == 'PyLauncher':
                continue

            with winreg.OpenKey(root_key, company) as company_key:
                for tag in enum_keys(company_key):
                    if (company, tag) in seen:
                        if company == 'PythonCore':
                            # TODO: Backwards compatibility handling
                            pass
                        continue
                    seen.add((company, tag))

                    try:
                        with winreg.OpenKey(company_key, tag + r'\InstallPath') as ip_key:
                            exec_path = get_value(ip_key, 'ExecutablePath')
                            exec_args = get_value(ip_key, 'ExecutableArguments')
                            if company == 'PythonCore' and not exec_path:
                                # TODO: Backwards compatibility handling
                                pass
                    except OSError:
                        exec_path, exec_args = None, None

                    if exec_path:
                        print('{}\\{} - {} {}'.format(company, tag, exec_path, exec_args or ''))
                    else:
                        print('{}\\{} - (not executable)'.format(company, tag))
  •  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章