有没有办法引用导入的变量名,如 HKEY_CLASSES_ROOT、HKEY_CURRENT_USER 等

0 投票
3 回答
596 浏览
提问于 2025-04-17 16:09

我一直在写一个函数,用来从Windows的注册表中读取一个值。这个函数看起来很啰嗦,而且重复的部分很多。我找不到其他方法来引用从winreg导入的变量,只能一个个地写出来。如果我能以某种方式引用这些变量,那代码就能简化很多,变得更简洁。有没有什么建议呢?

from winreg import *
import winreg
from tkinter import *
from tkinter import messagebox

# to read the (Default) value of a key, put a '.' at the end of the KeyString!

def mymessagebox(messagestr):
    root=Tk()
    root.withdraw()
    messagebox.showwarning('Warning!', messagestr)

def ReadRegValue(KeyString):
    try:
        KeyRoot, KeyFolder = KeyString.split('\\',1)
        if KeyFolder == '.':
            KeyFolder = ''
            Key = ''
        else:
            try:
                KeyFolder, Key = KeyFolder.rsplit('\\',1)
                if Key == '.':
                    Key = ''
            except ValueError:
                Key = ''
        if Key == '':
            if KeyRoot == 'HKEY_CLASSES_ROOT':
                try:
                    keyhandle = winreg.ConnectRegistry(None, HKEY_CLASSES_ROOT)
                    keyvalue = winreg.QueryValue(keyhandle, KeyFolder)
                    return keyvalue
                except FileNotFoundError:
                    mymessagebox(KeyFolder + ' not found in registry')
            elif KeyRoot == 'HKEY_CURRENT_USER':
                try:
                    keyhandle = winreg.ConnectRegistry(None, HKEY_CURRENT_USER)
                    keyvalue = winreg.QueryValue(keyhandle, KeyFolder)
                    return keyvalue
                except FileNotFoundError:
                    mymessagebox(KeyFolder + ' not found in registry')
            elif KeyRoot == 'HKEY_LOCAL_MACHINE':
                try:
                    keyhandle = winreg.ConnectRegistry(None, HKEY_LOCAL_MACHINE)
                    keyvalue = winreg.QueryValue(keyhandle, KeyFolder)
                    return keyvalue
                except FileNotFoundError:
                    mymessagebox(KeyFolder + ' not found in registry')
            elif KeyRoot == 'HKEY_USERS':
                try:
                    keyhandle = winreg.ConnectRegistry(None, HKEY_USERS)
                    keyvalue = winreg.QueryValue(keyhandle, KeyFolder)
                    return keyvalue
                except FileNotFoundError:
                    mymessagebox(KeyFolder + ' not found in registry')
            elif KeyRoot == 'HKEY_PERFORMANCE_DATA':
                try:
                    keyhandle = winreg.ConnectRegistry(None, HKEY_PERFORMANCE_DATA)
                    keyvalue = winreg.QueryValue(keyhandle, KeyFolder)
                    return keyvalue
                except FileNotFoundError:
                    mymessagebox(KeyFolder + ' not found in registry')
            elif KeyRoot == 'HKEY_CURRENT_CONFIG':
                try:
                    keyhandle = winreg.ConnectRegistry(None, HKEY_CURRENT_CONFIG)
                    keyvalue = winreg.QueryValue(keyhandle, KeyFolder)
                    return keyvalue
                except FileNotFoundError:
                    mymessagebox(KeyFolder + ' not found in registry')
            elif KeyRoot == 'HKEY_DYN_DATA':
                try:
                    keyhandle = winreg.ConnectRegistry(None, HKEY_DYN_DATA)
                    keyvalue = winreg.QueryValue(keyhandle, KeyFolder)
                    return keyvalue
                except FileNotFoundError:
                    mymessagebox(KeyFolder + ' not found in registry')
            else:
                mymessagebox(KeyRoot + ' is not a valid Key Root')
        else:
            if KeyRoot == 'HKEY_CLASSES_ROOT':
                try:
                    keyhandle = winreg.OpenKey(HKEY_CLASSES_ROOT, KeyFolder, 0, KEY_READ)
                    keyvalue, keytype = winreg.QueryValueEx(keyhandle, Key)
                    return keyvalue
                except FileNotFoundError:
                    mymessagebox(Key + ' not found in registry')
            elif KeyRoot == 'HKEY_CURRENT_USER':
                try:
                    keyhandle = winreg.OpenKey(HKEY_CURRENT_USER, KeyFolder, 0, KEY_READ)
                    keyvalue, keytype = winreg.QueryValueEx(keyhandle, Key)
                    return keyvalue
                except FileNotFoundError:
                    mymessagebox(Key + ' not found in registry')
            elif KeyRoot == 'HKEY_LOCAL_MACHINE':
                try:
                    keyhandle = winreg.OpenKey(HKEY_LOCAL_MACHINE, KeyFolder, 0, KEY_READ)
                    keyvalue, keytype = winreg.QueryValueEx(keyhandle, Key)
                    return keyvalue
                except FileNotFoundError:
                    mymessagebox(Key + ' not found in registry')
            elif KeyRoot == 'HKEY_USERS':
                try:
                    keyhandle = winreg.OpenKey(HKEY_USERS, KeyFolder, 0, KEY_READ)
                    keyvalue, keytype = winreg.QueryValueEx(keyhandle, Key)
                    return keyvalue
                except FileNotFoundError:
                    mymessagebox(Key + ' not found in registry')
            elif KeyRoot == 'HKEY_PERFORMANCE_DATA':
                try:
                    keyhandle = winreg.OpenKey(HKEY_PERFORMANCE_DATA, KeyFolder, 0, KEY_READ)
                    keyvalue, keytype = winreg.QueryValueEx(keyhandle, Key)
                    return keyvalue
                except FileNotFoundError:
                    mymessagebox(Key + ' not found in registry')
            elif KeyRoot == 'HKEY_CURRENT_CONFIG':
                try:
                    keyhandle = winreg.OpenKey(HKEY_CURRENT_CONFIG, KeyFolder, 0, KEY_READ)
                    keyvalue, keytype = winreg.QueryValueEx(keyhandle, Key)
                    return keyvalue
                except FileNotFoundError:
                    mymessagebox(Key + ' not found in registry')
            elif KeyRoot == 'HKEY_DYN_DATA':
                try:
                    keyhandle = winreg.OpenKey(HKEY_DYN_DATA, KeyFolder, 0, KEY_READ)
                    keyvalue, keytype = winreg.QueryValueEx(keyhandle, Key)
                    return keyvalue
                except FileNotFoundError:
                    mymessagebox(Key + ' not found in registry')
            else:
                mymessagebox(KeyRoot + ' is not a valid Key Root')
    except ValueError:
        mymessagebox('Your key string Must be in the format SOME_VALID_ROOT_KEY\folder\key .  To show a (Default) key value, put a "." at the end of your string.')
#
# Lets do some tests...
# 

results = ReadRegValue(r'HKEY_CLASSES_ROOT\.')
print (results)

3 个回答

0

在版本之后:

from winreg import *
import winreg
from tkinter import *
from tkinter import messagebox

# to read the (Default) value of a key, put a '.' at the end of the KeyString!

def mymessagebox(messagestr):
    root=Tk()
    root.withdraw()
    messagebox.showwarning('Warning!', messagestr)

def ReadRegValue(KeyString):
    validroots = {
    'HKEY_CLASSES_ROOT': HKEY_CLASSES_ROOT,
    'HKEY_CURRENT_USER':HKEY_CURRENT_USER,
    'HKEY_LOCAL_MACHINE': HKEY_LOCAL_MACHINE,
    'HKEY_USERS': HKEY_USERS,
    'HKEY_PERFORMANCE_DATA': HKEY_PERFORMANCE_DATA,
    'HKEY_CURRENT_CONFIG': HKEY_CURRENT_CONFIG,
    'HKEY_DYN_DATA': HKEY_DYN_DATA
}
    try:
        KeyRoot, KeyFolder = KeyString.split('\\',1)
        if KeyFolder == '.':
            KeyFolder = ''
            Key = ''
        else:
            try:
                KeyFolder, Key = KeyFolder.rsplit('\\',1)
                if Key == '.':
                    Key = ''
            except ValueError:
                Key = ''
        if KeyRoot in validroots:
            if Key == '':
                try:
                    keyhandle = winreg.ConnectRegistry(None, getattr(winreg, KeyRoot, None))
                    keyvalue = winreg.QueryValue(keyhandle, KeyFolder)
                    return keyvalue
                except FileNotFoundError:
                    mymessagebox('{} not found in registry'.format(KeyFolder))
            else:
                try:
                    keyhandle = winreg.OpenKey(getattr(winreg, KeyRoot, None), KeyFolder, 0, KEY_READ)
                    keyvalue, keytype = winreg.QueryValueEx(keyhandle, Key)
                    return keyvalue
                except FileNotFoundError:
                    mymessagebox('{} not found in registry'.format(Key))
        else:
            mymessagebox('{} is not a valid Key Root'.format(KeyRoot))
    except ValueError:
        mymessagebox('Your key string Must be in the format SOME_VALID_ROOT_KEY\folder\key .  To show a (Default) key value, put a "." at the end of your string.')
    return

#
# Lets do some tests...
# 
results = ReadRegValue(r'HKEY_CLASSES_ROOT\.')
print (results)
results = ReadRegValue(r'HKEY_CLASSES_ROOT\.7z\.')
print (results)
results = ReadRegValue(r'HKEY_CLASSES_ROOT\.ac3\PerceivedType')
print (results)
results = ReadRegValue(r'HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\1\ProcessorNameString')
print (results)
results = ReadRegValue(r'HKEY_CLASSES_ROOT\.')
print (results)
0

为什么不使用字典呢?

hives = {
    'HKEY_CLASSES_ROOT': HKEY_CLASSES_ROOT,
    'HKEY_CURRENT_USER': HKEY_CURRENT_USER,
    'HKEY_LOCAL_MACHINE': HKEY_LOCAL_MACHINE
}

if key_root in hives:
    try:
        key_handle = winreg.ConnectRegistry(None, hives[key_root])
        key_value = winreg.QueryValue(key_handle, key_folder)
        return key_value
    except FileNotFoundError:
        mymessagebox(key_folder + ' not found in registry')
0

确实,这样的写法非常重复。你可以使用 getattr() 这个函数来减少大部分重复的代码:

root = getattr(winreg, KeyRoot, None)
if root is None or not KeyRoot.startswith('HKEY_'):
    mymessagebox('{} is not a valid Key Root'.format(KeyRoot))
    return

if not Key:
    try:
        keyhandle = winreg.ConnectRegistry(None, root)
        return winreg.QueryValue(keyhandle, KeyFolder)
    except FileNotFoundError:
        mymessagebox('{} not found in registry'.format(KeyFolder))
else:
    try:
        keyhandle = winreg.OpenKey(root, KeyFolder, 0, KEY_READ)
        return winreg.QueryValueEx(keyhandle, Key)[0]
    except FileNotFoundError:
        mymessagebox('{} not found in registry'.format(KeyFolder))

撰写回答