Python3.11中winreg.SaveKey()返回WinError1314并生成空文件求助
解决Winreg.SaveKey报WinError 1314的问题
你遇到的问题核心是:管理员身份默认不包含SaveKey所需的备份/还原特权,虽然IsUserAnAdmin()返回True,但这两个特权在默认管理员会话里是禁用状态,必须手动启用才能正常调用SaveKey。
解决步骤
需要通过ctypes调整进程的特权状态,启用SeBackupPrivilege和SeRestorePrivilege,之后再执行SaveKey操作。以下是修正后的代码:
import winreg import ctypes from ctypes import wintypes # 定义所需的Windows API结构和函数 advapi32 = ctypes.WinDLL('advapi32', use_last_error=True) class LUID(ctypes.Structure): _fields_ = [ ('LowPart', wintypes.DWORD), ('HighPart', wintypes.LONG) ] class LUID_AND_ATTRIBUTES(ctypes.Structure): _fields_ = [ ('Luid', LUID), ('Attributes', wintypes.DWORD) ] class TOKEN_PRIVILEGES(ctypes.Structure): _fields_ = [ ('PrivilegeCount', wintypes.DWORD), ('Privileges', LUID_AND_ATTRIBUTES * 1) ] TOKEN_ADJUST_PRIVILEGES = 0x0020 TOKEN_QUERY = 0x0008 SE_PRIVILEGE_ENABLED = 0x00000002 def enable_privilege(privilege_name): htoken = wintypes.HANDLE() # 获取当前进程的令牌 if not advapi32.OpenProcessToken( ctypes.windll.kernel32.GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ctypes.byref(htoken) ): raise ctypes.WinError(ctypes.get_last_error()) try: luid = LUID() # 获取特权对应的LUID if not advapi32.LookupPrivilegeValueW( None, privilege_name, ctypes.byref(luid) ): raise ctypes.WinError(ctypes.get_last_error()) tp = TOKEN_PRIVILEGES() tp.PrivilegeCount = 1 tp.Privileges[0].Luid = luid tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED # 启用特权 if not advapi32.AdjustTokenPrivileges( htoken, False, ctypes.byref(tp), ctypes.sizeof(tp), None, None ): raise ctypes.WinError(ctypes.get_last_error()) # 检查特权是否成功启用 error = ctypes.get_last_error() if error == 1300: raise RuntimeError("特权未被授予") finally: ctypes.windll.kernel32.CloseHandle(htoken) # 启用备份和还原特权 enable_privilege('SeBackupPrivilege') enable_privilege('SeRestorePrivilege') # 验证管理员身份 print(ctypes.windll.shell32.IsUserAnAdmin()) # 应该返回True location = r"C:\Users\Key.reg" # 注意:打开键时用KEY_READ即可,SaveKey不需要KEY_ALL_ACCESS with winreg.OpenKey(winreg.HKEY_USERS, ".DEFAULT", access=winreg.KEY_READ) as key: winreg.SaveKey(key, location) # 验证文件内容 with open(location, 'r') as f: print(f.read())
关键说明
- 为什么需要这两个特权?Windows的
RegSaveKeyAPI(winreg.SaveKey底层调用的就是它)明确要求调用者拥有SeBackupPrivilege,否则会返回ERROR_PRIVILEGE_NOT_HELD(1314)。 - 打开注册表键时不需要
KEY_ALL_ACCESS,KEY_READ权限足够,减少不必要的权限风险。 - 特权启用后仅对当前进程有效,关闭进程后特权会自动失效。
内容的提问来源于stack exchange,提问作者kubinka0505
相关产品推荐
相关产品推荐

