Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

winreg.OpenKey throws filenotfound error for existing registry keys

I am facing difficulties in reading a registry key created by my software. However with the same code, I am able to read other keys.

installdir = winreg.OpenKey(
                            winreg.HKEY_LOCAL_MACHINE, 
                            "SOFTWARE\\Microsoft\\MediaPlayer\\Player\\Extensions\\Types"
                            ) #this works perfect
#installdir1 = winreg.OpenKey(
                              winreg.HKEY_LOCAL_MACHINE,
                             "SOFTWARE\\MySoftware\\MyEvent\\IS"
                             ) #this gives Filenotfound error

# list values owned by this registry key
try:
    i = 0
    while 1:
        name, value, type = winreg.EnumValue(installdir, i)
        print (repr(name))
        i += 1
except WindowsError:
    print ("Bot donf")
value, type = winreg.QueryValueEx(installdir, "10")
print("user is", repr(value))

value, type = winreg.QueryValueEx(winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\MySoftware\\MyEvent\\IS"), "v2")
print("user is", repr(value))

Traceback shows

 Traceback (most recent call last):
  File "D:/python_scripts/myclass.py", line 32, in <module>
    value, type = winreg.QueryValueEx(winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\MySoftware\\MyEvent\\IS"), "v2")
  FileNotFoundError: [WinError 2] The system cannot find the file specified

However Windows reg query is able to retrieve the value set.

#reg query HKLM\SOFTWARE\MySoftware\MyEvent\IS /v v2

HKEY_LOCAL_MACHINE\SOFTWARE\MySoftware\MyEvent\IS
v2    REG_DWORD    0x12

Any help will be highly appreciated

like image 656
Debianeese Avatar asked Jun 19 '15 07:06

Debianeese


1 Answers

There are 2 views of the registry. There is the 32-bit registry view and the 64-bit registry view. By default and in most cases, 32-bit applications will only see the the 32-bit registry view and 64-bit applications will only see the 64-bit registry view.

The other view can be accessed by using the KEY_WOW64_64KEY or the KEY_WOW64_32KEY access flags.

If you are running 32-bit python and your key is part of the 64-bit registry view, you should use something like this to open your key:

winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\MySoftware\\MyEvent\\IS", access=winreg.KEY_READ | winreg.KEY_WOW64_64KEY)

If you are running 64-bit python and your key is part of the 32-bit registry view, you should use something like this to open your key:

winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\MySoftware\\MyEvent\\IS", access=winreg.KEY_READ | winreg.KEY_WOW64_32KEY)

If you know the key is always part of the same view, adding the proper KEY_WOW64_* access flag will ensure that it works no matter what your python architecture is.

In the most generic case, if you have variable python architecture and you do not know in advance in which view the key will be, you can try finding the key in your current view and try the other view next. It could look something like this:

try:
    key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\MySoftware\\MyEvent\\IS")
except FileNotFoundError:
    import platform

    bitness = platform.architecture()[0]
    if bitness == '32bit':
        other_view_flag = winreg.KEY_WOW64_64KEY
    elif bitness == '64bit':
        other_view_flag = winreg.KEY_WOW64_32KEY

    try:
        key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\MySoftware\\MyEvent\\IS", access=winreg.KEY_READ | other_view_flag)
    except FileNotFoundError:
        '''
        We really could not find the key in both views.
        '''

For more information, check out Accessing an Alternate Registry View.

like image 161
Rémy Roy Avatar answered Oct 10 '22 13:10

Rémy Roy