17

I have developed a python script where i have a setting window which has the options to select the paths for the installation of software.When clicked on OK button of the setting window, i want to write all the selected paths to the registry and read the same when setting window is opened again. My code looks as below.

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)

I get a error like below:

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

And to read from registry,the saved registry has to show up in the setting window.I tried with the below code.Though its working but not satisfied with the way i programmed it.Help me out for the better solution

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)
Aramanethota
  • 613
  • 1
  • 7
  • 21

9 Answers9

31
#Python3 version of hugo24's snippet
import winreg

REG_PATH = r"Control Panel\Mouse"

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

#Example MouseSensitivity
#Read value 
print (get_reg('MouseSensitivity'))

#Set Value 1/20 (will just write the value to reg, the changed mouse val requires a win re-log to apply*)
set_reg('MouseSensitivity', str(10))

#*For instant apply of SystemParameters like the mouse speed on-write, you can use win32gui/SPI
#http://docs.activestate.com/activepython/3.4/pywin32/win32gui__SystemParametersInfo_meth.html
icc97
  • 8,746
  • 6
  • 60
  • 75
Mash
  • 411
  • 5
  • 8
  • So basically it's enough to remove the underscore from `_winreg` :) – Joril May 03 '18 at 15:11
  • 10
    There is a bug in this code. If there is an exception, CloseKey() will never get called. It is better to use `with winreg.OpenKey(...) as registry_key:` block, which will ensure that the key is closed when the block is exited, even when there is an exception. – Michael Krebs Oct 22 '18 at 14:35
15

Same as @Aramanethota but with pep8 and func def for easy usage.

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
hugo24
  • 994
  • 12
  • 21
9

Python script to read from registry is as follows:

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 script to write to the registry is:

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

Hope it helps you all.Cheers:)

Aramanethota
  • 613
  • 1
  • 7
  • 21
  • That part about `if not os.path.exists("keyval")` looks very wrong to me. On windows, it's looking for a file at `"C:\Users\YOURNAME\keyval"` to see if it exists, and it probably doesn't, so it calls `CreateKey()` every time. I don't see how that would ever work, even if you took the quotes off of it. – Cj Welborn May 05 '21 at 15:24
  • Also, `CreateKey()` just opens the key if it already exists. I would probably try to catch the `OSError` raised by `OpenKey()` if I was worried about the key not existing, and just use `CreateKey()` if I want to ensure it exists. – Cj Welborn May 05 '21 at 15:32
3

Reading registry keys:

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]

And writing:

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)

Extended for type handling. Provide type as argument, match current type in registry or python value type.

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)

NOTE: Use of contextlib.suppress() (available since python 3.4) can be replaced by try..except..pass for older versions. The context manager interface for winreg was introduced in python 2.6.

wihlke
  • 1,287
  • 11
  • 12
1

Looks like you don't have permission to edit the Registry. Incase if you are Admin, Please run this script in Elevated state.

Travis G
  • 1,534
  • 1
  • 13
  • 18
1

Here is a class I wrote (python 2) which has the ability to restore state when you finish manipulating the registry. The class was not tested properly so it may contain some bugs:

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()
Aviv
  • 552
  • 1
  • 3
  • 20
1

for Creating / writing values in registry key:

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)

If access denied - try running the command (CMd or IDE) in administrative mode

for reading value in registry-key

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("")
Deepan Raj
  • 305
  • 1
  • 5
  • 15
  • In the write example the statement "import winreg" is pointless. The variable "keyval" is better named "keypath". The key's valuename and the actual value are better defined by variables such as [valuename = "Start Page"] and [regszvalue = "snakes"]. – Hewey Dewey Jul 10 '20 at 05:30
0

My solution:

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
Nelles
  • 3,565
  • 6
  • 26
  • 39
  • There are 7 other answers to this question, one of them "accepted" (7 years ago). I cannot tell if this adds value -- perhaps if it was better formatted it might (just) ? – Chris Hall Mar 17 '20 at 13:09
0

The 'winreg' module is so ...strange working module, so, I wrote a class called 'WindowsRegistry' for working with Windows registry and 'winreg' module easier. I hope it will be more usefull:

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