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.

Attachment: OpenPGP_signature
Description: OpenPGP digital signature

-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to