скрипт python для чтения и записи пути к реестру

Я разработал скрипт Python, в котором у меня есть окно настроек, в котором есть параметры для выбора путей для установки программного обеспечения. При нажатии кнопки «ОК» в окне настроек я хочу записать все выбранные пути в реестр и прочитать то же самое, когда окно настроек снова открывается. Мой код выглядит так, как показано ниже.

def OnOk(self, event):
    data1=self.field1.GetValue() #path selected in setting window
    aReg = ConnectRegistry(None,HKEY_LOCAL_MACHINE)
    keyVal=OpenKey(aReg,r"SOFTWARE\my path to\Registry", 0,KEY_WRITE)
    try:
       SetValueEx(keyVal,"Log file",0,REG_SZ,data1)
    except EnvironmentError:
       pass
    CloseKey(keyVal)
    CloseKey(aReg)

Я получаю сообщение об ошибке, как показано ниже:

Traceback (most recent call last):
File "D:\PROJECT\project.py", line 305, in OnOk
keyVal=OpenKey(aReg,r"SOFTWARE\my path to\Registry", 0,KEY_WRITE)
WindowsError: [Error 5] Access is denied

И чтобы прочитать из реестра, сохраненный реестр должен отображаться в окне настроек. Я пробовал с приведенным ниже кодом. Хотя он работает, но не удовлетворен тем, как я его запрограммировал. Помогите мне найти лучшее решение

key = OpenKey(HKEY_CURRENT_USER, r'Software\my path to\Registry', 0, KEY_READ)
    for i in range(4): 
        try:
            n,v,t = EnumValue(key,i)
            if i==0:
                self.field2.SetValue(v)
            elif i==1:
                self.field3.SetValue(v)
            elif i==2:
                self.field4.SetValue(v)
            elif i==3:
                self.field1.SetValue(v)
        except EnvironmentError:                                               
            pass
CloseKey(key)

person Aramanethota    schedule 28.02.2013    source источник


Ответы (9)


То же, что и @Aramanethota, но с pep8 и func def для простоты использования.

REG_PATH = r"SOFTWARE\my_program\Settings"

def set_reg(name, value):
    try:
        _winreg.CreateKey(_winreg.HKEY_CURRENT_USER, REG_PATH)
        registry_key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, REG_PATH, 0, 
                                       _winreg.KEY_WRITE)
        _winreg.SetValueEx(registry_key, name, 0, _winreg.REG_SZ, value)
        _winreg.CloseKey(registry_key)
        return True
    except WindowsError:
        return False

def get_reg(name):
    try:
        registry_key = _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, REG_PATH, 0,
                                       _winreg.KEY_READ)
        value, regtype = _winreg.QueryValueEx(registry_key, name)
        _winreg.CloseKey(registry_key)
        return value
    except WindowsError:
        return None
person hugo24    schedule 13.05.2014

Скрипт Python для чтения из реестра выглядит следующим образом:

try:
    root_key=OpenKey(HKEY_CURRENT_USER, r'SOFTWARE\my path to\Registry', 0, KEY_READ)
    [Pathname,regtype]=(QueryValueEx(root_key,"Pathname"))
    CloseKey(root_key)
    if (""==Pathname):
        raise WindowsError
except WindowsError:
    return [""]

Скрипт Python для записи в реестр:

try:
    keyval=r"SOFTWARE\my path to\Registry"
    if not os.path.exists("keyval"):
        key = CreateKey(HKEY_CURRENT_USER,keyval)
    Registrykey= OpenKey(HKEY_CURRENT_USER, r"SOFTWARE\my path to\Registry", 0,KEY_WRITE)
    SetValueEx(Registrykey,"Pathname",0,REG_SZ,Pathname)
    CloseKey(Registrykey)
    return True
except WindowsError:
    return False

Надеюсь, это поможет вам всем. Ура :)

person Aramanethota    schedule 03.04.2013
comment
Эта часть о if not os.path.exists("keyval") кажется мне очень неправильной. В Windows он ищет файл по адресу "C:\Users\YOURNAME\keyval", чтобы узнать, существует ли он, и, вероятно, его нет, поэтому он каждый раз вызывает CreateKey(). Я не понимаю, как это когда-нибудь сработает, даже если вы уберете кавычки. - person Cj Welborn; 05.05.2021
comment
Кроме того, CreateKey() просто открывает ключ, если он уже существует. Я бы, вероятно, попытался поймать OSError, вызванный OpenKey(), если бы я беспокоился о том, что ключ не существует, и просто использовал бы CreateKey(), если я хочу убедиться, что он существует. - person Cj Welborn; 05.05.2021

Чтение ключей реестра:

def read(path, root=HKEY_CURRENT_USER):
    path, name = os.path.split(path)
    with suppress(FileNotFoundError), OpenKey(root, path) as key:
        return QueryValueEx(key, name)[0]

И писать:

def write(path, value, root=HKEY_CURRENT_USER):
    path, name = os.path.split(path)
    with OpenKey(root, path, 0, KEY_WRITE) as key:
        SetValueEx(key, name, 0, REG_SZ, value)

Расширен для обработки типов. Укажите тип в качестве аргумента, соответствующий текущему типу в реестре или типу значения python.

def write(path, value, root=HKEY_CURRENT_USER, regtype=None):
    path, name = os.path.split(path)
    with OpenKey(root, path, 0, KEY_WRITE|KEY_READ) as key:
        with suppress(FileNotFoundError):
            regtype = regtype or QueryValueEx(key, name)[1]

        SetValueEx(key, name, 0, regtype or REG_DWORD if isinstance(value, int) else REG_SZ, str(value) if regtype==REG_SZ else value)

ПРИМЕЧАНИЕ. Использование contextlib.suppress() (доступно с python 3.4) можно заменить на try..except..pass для более старых версий. Интерфейс контекстного менеджера для winreg был представлен в python 2.6 .

person wihlke    schedule 21.01.2019

Похоже, у вас нет прав на редактирование реестра. Если вы являетесь администратором, пожалуйста, запустите этот скрипт с повышенными правами.

person Travis G    schedule 28.02.2013
comment
Да, я использовал гостевого пользователя, поэтому я не понял правильно. Я изменил HKEY_LOCAL_MACHINE на HKEY_CURRENT_USER, и теперь он работает нормально. - person Aramanethota; 28.02.2013
comment
HKEY_CURRENT_USER работает как для администратора, так и для другой учетной записи пользователя?? - person Aramanethota; 28.02.2013
comment
Если пользователь-гость может получить доступ к ключу в реестре, то и администратор может. - person Travis G; 28.02.2013
comment
Спасибо @Travis G. Я выберу HKEY_CURRENT USER. - person Aramanethota; 28.02.2013

Вот класс, который я написал (python 2), который имеет возможность восстанавливать состояние, когда вы заканчиваете манипулировать реестром. Класс не был протестирован должным образом, поэтому он может содержать некоторые ошибки:

import _winreg as winreg

class Registry(object):
    def __init__(self, restore_state=False):
        self.m_backup = {}
        self.m_restore_state = restore_state

    def get_key(self, hkey, subkey, access, create_if_doesnt_exist=True):
        created_key = False
        registry_key = None
        try:
            registry_key = winreg.OpenKey(hkey, subkey, 0, access)
        except WindowsError:
            try:
                if create_if_doesnt_exist:
                    registry_key = winreg.CreateKey(hkey, subkey)
                    if registry_key not in self.m_backup:
                        self.m_backup[registry_key] = ({}, (hkey, subkey))
                else:
                    registry_key = None
            except WindowsError:
                if registry_key:
                    self.close_key(registry_key)
                raise Exception('Registry does not exist and could not be created.')
        return registry_key   

    def close_key(self, registry_key):
        closed = False
        if registry_key:
            try:
                winreg.CloseKey(registry_key)
                closed = True
            except:
                closed = False
        return closed          

    def get_reg_value(self, hkey, subkey, name):
        value = None
        registry_key = self.get_key(hkey, subkey, winreg.KEY_READ, False)
        if registry_key:
            try:
                value, _ = winreg.QueryValueEx(registry_key, name)
            except WindowsError:
                value = None
            finally:
                self.close_key(registry_key)
        return value

    def set_reg_value(self, hkey, subkey, name, type, value):
        registry_key = self.get_key(hkey, subkey, winreg.KEY_WRITE, True)
        backed_up = False
        was_set = False
        if registry_key:
            if self.m_restore_state:
                if registry_key not in self.m_backup:
                    self.m_backup[registry_key] = ({}, None)
                existing_value = self.get_reg_value(hkey, subkey, name)
                if existing_value:
                    self.m_backup[registry_key][0][name] = (existing_value, type, False)
                else:
                    self.m_backup[registry_key][0][name] = (None, None, True)
                backed_up = True                
            try:
                winreg.SetValueEx(registry_key, name, 0, type, value)
                was_set = True
            except WindowsError:
                was_set = False
            finally:
                if not backed_up:
                    self.close_key(registry_key)
        return was_set

    def restore_state(self):
        if self.m_restore_state:
            for registry_key, data in self.m_backup.iteritems():
                backup_dict, key_info = data
                try:
                    for name, backup_data in backup_dict.iteritems():
                        value, type, was_created = backup_data
                        if was_created:
                            print registry_key, name
                            winreg.DeleteValue(registry_key, name)
                        else:
                            winreg.SetValueEx(registry_key, name, 0, type, value)
                    if key_info:
                        hkey, subkey = key_info
                        winreg.DeleteKey(hkey, subkey)
                except:
                    raise Exception('Could not restore value')
                self.close_key(registry_key)

    def __del__(self):
        if self.m_restore_state:
            self.restore_state()
person Aviv    schedule 16.11.2016

для создания/записи значений в раздел реестра:

from winreg import*
import winreg

keyVal = r'SOFTWARE\\python'


try:
    key = OpenKey(HKEY_LOCAL_MACHINE, keyVal, 0, KEY_ALL_ACCESS)
except:
    key = CreateKey(HKEY_LOCAL_MACHINE, keyVal)
SetValueEx(key, "Start Page", 0, REG_SZ, "snakes")
CloseKey(key)

Если доступ запрещен - попробуйте запустить команду (CMd или IDE) в административном режиме

для чтения значения в разделе реестра

from winreg import*
Registry = ConnectRegistry(None, HKEY_LOCAL_MACHINE)
RawKey = OpenKey(Registry, "SOFTWARE\\python")
try:
    i = 0
    while 1:
        name, value, type = EnumValue(RawKey, i)
        print("name:",name,"value:", value,"i:", i)
        i += 1
except WindowsError:
    print("")
person Deepan Raj    schedule 03.07.2019
comment
В примере записи оператор import winreg не имеет смысла. Переменную keyval лучше назвать keypath. Имя значения ключа и фактическое значение лучше определяются переменными, такими как [valuename = Start Page] и [regszvalue = змеи]. - person Hewey Dewey; 10.07.2020

Мое решение:

def add_key(name,pathh):
    try:
        keyval=r"System\my path\Register"
        if not os.path.exists("keyval"):
            key = winreg.CreateKey(winreg.HKEY_CURRENT_USER,keyval)
        Registrykey = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"System\my path\Register", 0,winreg.KEY_WRITE)
        winreg.SetValueEx(Registrykey,name,1,winreg.REG_SZ,pathh)
        winreg.CloseKey(Registrykey)
        return True
    except WindowsError:
        return False
person Omer Barzilay    schedule 17.03.2020
comment
На этот вопрос есть 7 других ответов, один из них принят (7 лет назад). Я не могу сказать, добавляет ли это ценности - возможно, если бы это было лучше отформатировано, это могло бы (просто)? - person Chris Hall; 17.03.2020

Модуль 'winreg' такой... странный рабочий модуль, поэтому я написал класс 'WindowsRegistry' для упрощения работы с реестром Windows и модулем 'winreg'. Я надеюсь, что это будет более полезно:

import winreg
import re


class WindowsRegistry:
    """Class WindowsRegistry is using for easy manipulating Windows registry.


    Methods
    -------
    query_value(full_path : str)
        Check value for existing.

    get_value(full_path : str)
        Get value's data.

    set_value(full_path : str, value : str, value_type='REG_SZ' : str)
        Create a new value with data or set data to an existing value.

    delete_value(full_path : str)
        Delete an existing value.

    query_key(full_path : str)
        Check key for existing.

    delete_key(full_path : str)
        Delete an existing key(only without subkeys).


    Examples:
        WindowsRegistry.set_value('HKCU/Software/Microsoft/Windows/CurrentVersion/Run', 'Program', r'"c:\Dir1\program.exe"')
        WindowsRegistry.delete_value('HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Run/Program')
    """
    @staticmethod
    def __parse_data(full_path):
        full_path = re.sub(r'/', r'\\', full_path)
        hive = re.sub(r'\\.*$', '', full_path)
        if not hive:
            raise ValueError('Invalid \'full_path\' param.')
        if len(hive) <= 4:
            if hive == 'HKLM':
                hive = 'HKEY_LOCAL_MACHINE'
            elif hive == 'HKCU':
                hive = 'HKEY_CURRENT_USER'
            elif hive == 'HKCR':
                hive = 'HKEY_CLASSES_ROOT'
            elif hive == 'HKU':
                hive = 'HKEY_USERS'
        reg_key = re.sub(r'^[A-Z_]*\\', '', full_path)
        reg_key = re.sub(r'\\[^\\]+$', '', reg_key)
        reg_value = re.sub(r'^.*\\', '', full_path)

        return hive, reg_key, reg_value

    @staticmethod
    def query_value(full_path):
        value_list = WindowsRegistry.__parse_data(full_path)
        try:
            opened_key = winreg.OpenKey(getattr(winreg, value_list[0]), value_list[1], 0, winreg.KEY_READ)
            winreg.QueryValueEx(opened_key, value_list[2])
            winreg.CloseKey(opened_key)
            return True
        except WindowsError:
            return False

    @staticmethod
    def get_value(full_path):
        value_list = WindowsRegistry.__parse_data(full_path)
        try:
            opened_key = winreg.OpenKey(getattr(winreg, value_list[0]), value_list[1], 0, winreg.KEY_READ)
            value_of_value, value_type = winreg.QueryValueEx(opened_key, value_list[2])
            winreg.CloseKey(opened_key)
            return value_of_value
        except WindowsError:
            return None

    @staticmethod
    def set_value(full_path, value, value_type='REG_SZ'):
        value_list = WindowsRegistry.__parse_data(full_path)
        try:
            winreg.CreateKey(getattr(winreg, value_list[0]), value_list[1])
            opened_key = winreg.OpenKey(getattr(winreg, value_list[0]), value_list[1], 0, winreg.KEY_WRITE)
            winreg.SetValueEx(opened_key, value_list[2], 0, getattr(winreg, value_type), value)
            winreg.CloseKey(opened_key)
            return True
        except WindowsError:
            return False

    @staticmethod
    def delete_value(full_path):
        value_list = WindowsRegistry.__parse_data(full_path)
        try:
            opened_key = winreg.OpenKey(getattr(winreg, value_list[0]), value_list[1], 0, winreg.KEY_WRITE)
            winreg.DeleteValue(opened_key, value_list[2])
            winreg.CloseKey(opened_key)
            return True
        except WindowsError:
            return False

    @staticmethod
    def query_key(full_path):
        value_list = WindowsRegistry.__parse_data(full_path)
        try:
            opened_key = winreg.OpenKey(getattr(winreg, value_list[0]), value_list[1] + r'\\' + value_list[2], 0, winreg.KEY_READ)
            winreg.CloseKey(opened_key)
            return True
        except WindowsError:
            return False

    @staticmethod
    def delete_key(full_path):
        value_list = WindowsRegistry.__parse_data(full_path)
        try:
            winreg.DeleteKey(getattr(winreg, value_list[0]), value_list[1] + r'\\' + value_list[2])
            return True
        except WindowsError:
            return False
person Aleksandr Ivannikov    schedule 24.10.2020
comment
проверено? Ваши переменные set_value и примеры кажутся конфликтующими - person naturesenshi; 10.03.2021

person    schedule
comment
Так что в принципе достаточно убрать подчеркивание с _winreg :) - person Joril; 03.05.2018
comment
В этом коде есть ошибка. Если есть исключение, CloseKey() никогда не будет вызвана. Лучше использовать блок with winreg.OpenKey(...) as registry_key:, который обеспечит закрытие ключа при выходе из блока, даже при возникновении исключения. - person Michael Krebs; 22.10.2018