Eryk Many thanks. It is working perfectly now. See below for the reworked code.
Cheers Mike On 13/05/2022 1:42 pm, Eryk Sun wrote:
On 5/12/22, Mike Dewhirst<mi...@dewhirst.com.au> wrote:access=wr.KEY_ALL_ACCESS + wr.KEY_WRITE,
import winreg as wr class Registry: def __init__(self, computer=None, hkey=None, sub_key=None): self.computer = computer self.key = hkey self.sub_key = sub_key def connect(self): return wr.ConnectRegistry(self.computer, self.key) def select(self, access=None): with self.connect() as hkey: return wr.OpenKeyEx(key=hkey, sub_key=self.sub_key, access=access) def count(self): access = wr.KEY_QUERY_VALUE return wr.QueryInfoKey(self.select(access=access)) def query(self, vname, access=None): if access is None: access = wr.KEY_READ | wr.KEY_WOW64_32KEY return wr.QueryValueEx(self.select(access=access), vname) def setvalue(self, vname, value, access=None): if access is None: access = wr.KEY_SET_VALUE with self.select(access=access) as hkey: return wr.SetValueEx(hkey, vname, 0, wr.REG_SZ, value) if __name__ == "__main__": lmregistry = Registry( hkey=wr.HKEY_LOCAL_MACHINE, sub_key=r"SOFTWARE\XXX Technology\AppName", ) print(f"\n{lmregistry.sub_key}") anz = lmregistry.query('Country')[0] print(f"\n{anz}") db = lmregistry.query('Database')[0] print(f"\n{db}") devref = lmregistry.query('v135')[0] print(f"\n{devref}") orgid = lmregistry.query('v136')[0] print(f"\n{orgid}") curegistry = Registry( hkey=wr.HKEY_CURRENT_USER, sub_key=r"SOFTWARE\XXX Technology\AppName", ) print(f"\n{curegistry.sub_key}") anz = curegistry.query('Country')[0] print(f"\n{anz}") db = curegistry.query('Database')[0] print(f"\n{db}") devref = curegistry.query('v135')[0] print(f"\n{devref}") orgid = curegistry.query('v136')[0] print(f"\n{orgid}") curegistry.setvalue('Country', 'nz') curegistry.setvalue('Database', '2022.2') curegistry.setvalue('v135', 'Asus10') curegistry.setvalue('v136', orgid.replace('ALL', 'Most')) anz = curegistry.query('Country')[0] print(f"\n{anz}") db = curegistry.query('Database')[0] print(f"\n{db}") devref = curegistry.query('v135')[0] print(f"\n{devref}") orgid = curegistry.query('v136')[0] print(f"\n{orgid}")
Again, many thanks for putting so much effort into educating me. Cheers Mike
The access parameter is a bit mask of access rights that combine via bitwise OR (|), not via arithmetic addition. KEY_ALL_ACCESS (0x000F_003F) is a superset of KEY_WRITE (0x0002_0006): KEY_WRITE = ( READ_CONTROL | # 0x0002_0000 KEY_SET_VALUE | # 0x0000_0002 KEY_CREATE_SUB_KEY | # 0x0000_0004 ) # 0x0002_0006 KEY_ALL_ACCESS = ( DELETE | # 0x0001_0000 READ_CONTROL | # 0x0002_0000 WRITE_DAC | # 0x0004_0000 WRITE_OWNER | # 0x0008_0000 KEY_QUERY_VALUE | # 0x0000_0001 KEY_SET_VALUE | # 0x0000_0002 KEY_CREATE_SUB_KEY | # 0x0000_0004 KEY_ENUMERATE_SUB_KEYS | # 0x0000_0008 KEY_NOTIFY | # 0x0000_0010 KEY_CREATE_LINK | # 0x0000_0020 ) # 0x000F_003F The result of the arithmetic addition `KEY_ALL_ACCESS + KEY_WRITE` is 0x0011_0045, which is wrong and meaningless. Registry key objects do not support SYNCHRONIZE (0x0010_0000) access; DELETE (0x0001_0000) access isn't needed; 0x0000_0040 is not a supported key right; KEY_CREATE_SUB_KEY (0x0000_0004) access isn't needed; and KEY_QUERY_VALUE (0x0000_0001) isn't sufficient. You should limit the requested access to the specific access rights that are required for querying and setting values in the key: access=(wr.KEY_QUERY_VALUE | wr.KEY_SET_VALUE)def setvalue(self, vname, value): return wr.SetValueEx(self.select(), vname, 0, 1, value)You shouldn't hard code the value of the data type constant. Use wr.REG_SZ instead of 1. The return value of self.select() is a winreg PyHKEY object that wraps the OS handle for the key object. You're relying on implicit closing of this handle based on referencing counting. It's cleaner to use it in a `with` statement, as you would for a file object returned by open(). For example: with self.select() as hkey: wr.SetValueEx(hkey, vname, 0, wr.REG_SZ, value)lmregistry = Registry( hkey=wr.HKEY_LOCAL_MACHINE, sub_key="SOFTWARE\WOW6432Node\XXX Technology\AppName",You really shouldn't open the "WOW6432Node" key directly. It is an implementation detail of the WOW64 subsystem that runs 32-bit applications on a 64-bit system. If you need to operate on the registry keys of 32-bit applications from a native 64-bit process, open the normal path using the access right KEY_WOW64_32KEY (0x0000_0200). For example: hkey = wr.HKEY_LOCAL_MACHINE subkey = r"SOFTWARE\XXX Technology\AppName" access = ( wr.KEY_QUERY_VALUE | wr.KEY_SET_VALUE | wr.KEY_WOW64_32KEY ) Typically you'd first try opening the path without either KEY_WOW64_32KEY or KEY_WOW64_64KEY. The default view matches the current process. https://docs.microsoft.com/en-us/windows/win32/winprog64/accessing-an-alternate-registry-view Remember to escape the backslash separators in string literals of key paths, or use raw string literals as I used in the above example.
-- Signed email is an absolute defence against phishing. This email has been signed with my private key. If you import my public key you can automatically decrypt my signature and be sure it came from me. Just ask and I'll send it to you. Your email software can handle signing.
OpenPGP_signature
Description: OpenPGP digital signature
-- https://mail.python.org/mailman/listinfo/python-list