Python: WindowsError when editing Registry values using _winreg on Windows 7

1.7k Views Asked by At

I am trying to execute this script by Ned Batchelder to switch .py file association between my two Python installations on Windows. This Python script uses the _winreg module (winreg in Python 3.x) to edit certain Registry values (the path and value pairs modified can be seen in the todo list in the script).

I execute this script as follows:

> SwitchPy.py "C:\Program Files\Python26"

I am getting the following error:

Traceback (most recent call last):
  File "C:\Users\SuperUser\SwitchPy.py", line 30, in <module>
    key = reg.OpenKey(classes_root, path, 0, reg.KEY_SET_VALUE)
WindowsError: [Error 5] Access is denied

I guessed that it could be something to do with account permissions. But, note that:

  • The account used above is part of the Administrators group and has admin privileges.

  • With the above account I can execute regedit.exe and manually set the values listed in the script without facing any permissions or access problems.

I am using Windows 7 and am part of a domain. Could any of this have something to do with this problem?

Does anyone have any clue about this error? How do I make this script run?

2

There are 2 best solutions below

1
On

When I tried that one, I got "Path not found" error on Python.CompiledFile.

I checked it on my registry, it does not exist, not Windows 7 though.

So, I removed those lines of Python.CompiledFile and its running fine here, or

You could put try: except: On OpenKey and SetValue, not good idea though.

0
On

I was able to run the script by opening a command prompt using the "Run as Administrator".

It appears that you can only maintain HKEY_LOCAL_MACHINE entries if you run the script with elevated authorities.

Some of the HKEY_CLASSES_ROOT entries come from HKEY_LOCAL_MACHINE according to this MSDN link:

The HKEY_CLASSES_ROOT subtree is a view formed by merging HKEY_CURRENT_USER\Software\Classes and HKEY_LOCAL_MACHINE\Software\Classes

I updated the script to include the suggested try/except in addition to a few print statements for extra feedback.

Here is how I updated the script:

""" Change the .py file extension to point to a different
    Python installation.
"""
import _winreg as reg
import sys

pydir = sys.argv[1]

todo = [
    ('Applications\python.exe\shell\open\command',
                '"PYDIR\\python.exe" "%1" %*'),
    ('Applications\pythonw.exe\shell\open\command',
                '"PYDIR\\pythonw.exe" "%1" %*'),
    ('Python.CompiledFile\DefaultIcon',
                'PYDIR\\pyc.ico'),
    ('Python.CompiledFile\shell\open\command',
                '"PYDIR\\python.exe" "%1" %*'),
    ('Python.File\DefaultIcon',
                'PYDIR\\py.ico'),
    ('Python.File\shell\open\command',
                '"PYDIR\\python.exe" "%1" %*'),
    ('Python.NoConFile\DefaultIcon',
                'PYDIR\\py.ico'),
    ('Python.NoConFile\shell\open\command',
                '"PYDIR\\pythonw.exe" "%1" %*'),
    ]

classes_root = reg.OpenKey(reg.HKEY_CLASSES_ROOT, "")
for path, value in todo:
    print "Updating %s with %s" % (path, value.replace('PYDIR', pydir))
    try:
        key = reg.OpenKey(classes_root, path, 0, reg.KEY_SET_VALUE)
        reg.SetValue(key, '', reg.REG_SZ, value.replace('PYDIR', pydir))
    except:
        print "Unable to maintain %s\n" % (path)