Python’s _winreg: Editing the Windows Registry

Python’s standard library is known for including lots of handy modules and packages that can be used without installing anything else. That’s one of the primary reasons that its standard library is called “batteries included” so often. So it should come as no surprise that Python includes a Windows only module for editing the Windows Registry. This particular module goes by the odd name of _winreg (odd because it starts with an underscore). In this article, we’ll learn the basics of working with the Registry using this “battery”.

Reading from the Registry

Using Python to read data from the registry is very easy. In the following example, we’ll find out where Outlook Express is installed:

from _winreg import *
key = OpenKey(HKEY_LOCAL_MACHINE, r'Software\Microsoft\Outlook Express', 0, KEY_ALL_ACCESS)
QueryValueEx(key, "InstallRoot")

On my machine, this will return the following tuple: (u’%ProgramFiles%\\Outlook Express’, 2). The tuple is made up of the value and the registry type of said value. There are two other query methods that one can use called QueryInfoKey and QueryValue. The former gives you information about the key itself in form of three integers while the latter retrieves only the data for a key’s first value that has a NULL name. The documentation recommends that you use QueryValueEx whenever possible.

We should probably quickly explain what’s going on in the code above as well. The OpenKey function takes an HKEY* constant, a subkey path string, a reserved integer (which must be zero) and the security mask. In this case, we passed in KEY_ALL_ACCESS which gives us complete control of that key. Since all we were doing was reading it, we probably should have just used KEY_READ though. As for what QueryValueEx does, it just accepts a key object and the field name that we want to query against.

Writing to the Registry

If you’ve been reading this blog lately, then you’ve probably already seen the _winreg module used for writing to the registry. This will just be review for you, so feel free to skip this section. We’ll start out with a practical example. In the following code snippet, we will set Internet Explorer’s home page. As always, please note that editing Registry entries can be dangerous. IMPORTANT: Be sure to back up your registry before attempting to edit it. Now, on with the show!

keyVal = r'Software\Microsoft\Internet Explorer\Main'
try:
    key = OpenKey(HKEY_CURRENT_USER, keyVal, 0, KEY_ALL_ACCESS)
except:
    key = CreateKey(HKEY_CURRENT_USER, keyVal)
SetValueEx(key, "Start Page", 0, REG_SZ, "https://www.blog.pythonlibrary.org/")
CloseKey(key)

In the code above, we attempt to open the following key: HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main and set the “Start Page” value to this blog. If the open fails, it’s usually because the key doesn’t exist, so we try to create the key in our exception handler. Then we use SetValueEx to actually set the value and like all good programmers, we clean up when we’re done and close the key. If you skipped the CloseKey command, you’d be fine in this case as the script is done and Python will do it for you. However, if you continued working on this key, you might have an access violation since it’s already open. Thus, the lesson is to always close a key when you finish editing it.

Other _winreg Methods

There are several other methods in the _winreg library worth pointing out. The DeleteKey method is handy when you need to remove a key. Unfortunately, I’ve had occasion when I need to remove keys recursively, such as when an uninstall goes bad and _winreg has no built-in way of doing that. You can write your own, of course, or you can download a wrapper like YARW (Yet Another Registry Wrapper) that can do it for you.

DeleteValue is similar to DeleteKey, except that you delete just a value. Yes, it’s pretty obvious. If you’d wanted to write your own recursive key deleting code, then you’d probably want to take a look at EnumKey and EnumValue as they enumerate keys and values respectively. Let’s take a quick look at how to use EnumKey:

from _winreg import EnumKey, HKEY_USERS

try:
    i = 0
    while True:
        subkey = EnumKey(HKEY_USERS, i)
        print subkey
        i += 1
except WindowsError:
    # WindowsError: [Errno 259] No more data is available    
    pass

The code above will loop through the HKEY_USERS hive printing the subkey to stdout until we reach the end of the hive and a WindowsError is raised. Of course, this does not descend into the subkeys, but I’ll leave that as an exercise for the reader to figure out.

The last method that we’ll talk about here is ConnectRegistry. This is helpful if we need to edit the Registry of a remote machine. It only accepts two arguments: the computer name and the key to connect to (i.e. HKEY_LOCAL_MACHINE or some such). Note that when connecting to remote machines, you can only edit certain keys while the others are unavailable.

Wrapping Up

I hope this was helpful for you and that it gave you lots of good ideas for your future projects. I have many login scripts that use this wonderful library and a couple that use YARW. It’s been quite useful so far and I hope that it will be the same for you.

UPDATE (10/14/2011): We now have a Brazilian Portuguese translation of this post up on Carlisson Galdino’s blog

Further Reading

2 thoughts on “Python’s _winreg: Editing the Windows Registry”

  1. I've tried editing my Registry entries once because I didn't have a clean registry. I've lost almost everything, because the tutorial I was doing this after didn't mention that I should had been sure to back up the registry before attempting to edit it. This makes me trust your post more, you are careful about the details.

Comments are closed.