我开发了一个Python脚本,其中有一个设置窗口,其中包含选择软件安装路径的选项。当单击设置窗口的“确定”按钮时,我想将所有选定的路径写入注册表并读取再次打开设置窗口时也是如此。 我的代码如下所示。
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)
我收到如下错误:
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
要从注册表中读取,保存的注册表必须显示在设置窗口中。我尝试使用下面的代码。虽然它可以工作,但对我编程的方式不满意。帮助我找到更好的解决方案
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)
#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
与 @Aramanethota 相同,但使用 pep8 和 func def 以便于使用。
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
从注册表读取的Python脚本如下:
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脚本是:
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
希望对大家有帮助。干杯:)
读取注册表项:
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]
并写道:
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)
针对类型处理进行了扩展。提供类型作为参数,匹配注册表中的当前类型或 python 值类型。
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)
注意: 对于旧版本,contextlib.suppress()(自
起可用)的使用可以替换为 try.. except..pass 。 winreg 的上下文管理器界面在python 3.4
中引入。python 2.6
您似乎没有编辑注册表的权限。如果您是管理员,请在提升状态下运行此脚本。
这是我编写的一个类(python 2),它能够在完成注册表操作后恢复状态。该类未经过正确测试,因此可能包含一些错误:
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()
用于在注册表项中创建/写入值:
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)
如果访问被拒绝 - 尝试在管理模式下运行命令(CMd 或 IDE)
用于读取注册表项中的值
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("")
我的解决方案:
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
“winreg”模块是如此......奇怪的工作模块,因此,我编写了一个名为“WindowsRegistry”的类,以便更轻松地使用 Windows 注册表和“winreg”模块。我希望它会更有用:
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
在这里很难提出新的东西,但我看到很多答案都遗漏了一些重要的怪癖。
最重要的一点是,如果您对权限贪婪,您将无法读取密钥,而可以写入(反之亦然)。在这种情况下,read操作不会抛出异常,你将不知道发生了什么。所以请务必使用:
winreg.KEY_ALL_ACCESS
。
这里的示例脚本读取 Windows (API) 的
ENABLE_VIRTUAL_TERMINAL_PROCESSING
注册表设置,位于:Computer\HKEY_CURRENT_USER\Console
,并由名称给出:VirtualTerminalLevel
。
import winreg as wrg
RIGHTS = wrg.KEY_ALL_ACCESS # Enable Write Permissions to Regsitry Hive [KEY_ALL_ACCESS]
HKCU = wrg.HKEY_CURRENT_USER # The HKCU Hive
VTL = r'Console\\' # VT Location/Path
VTK = 'VirtualTerminalLevel' # VT Registry Key Name for (Windows) ENABLE_VIRTUAL_TERMINAL_PROCESSING
VTH = wrg.OpenKeyEx(HKCU, VTL, 0, RIGHTS)
VT = wrg.QueryValueEx(VTH, VTK)[0]
wrg.CloseKey(VTH)
print(VT)
# 1
为了保持代码的必要性(并在 REPL 中正常运行),这里根本没有检查!所以你必须自己实现这些。