Module winregistry

This module contains procedures that provide access to Windows Registry.

Please do not use this module to save your applications settings, use it to interact with older programs which make use of registry, because it is slow (implemented as file system inside a file rather than database), not cross-platform, has unoblivious stuff like registry virtualization, virtual storages, different behavior across 32/64-bit systems. As alternative you can supply some kind of INI or XML file with your application or store it into platform-specific settings folder (take a look at appdirs module).

Notes

# actually opens HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Adobe
var a = open("HKEY_LOCAL_MACHINE\\SOFTWARE\\Adobe", samRead)
# now it is properly opened HKEY_LOCAL_MACHINE\Software\Adobe
var b = open("HKEY_LOCAL_MACHINE\\SOFTWARE\\Adobe", samRead or samWow64)
# actually creates HKEY_USERS\<User SID>_Classes\VirtualStore\Machine\Software\test
var c = create("HKEY_LOCAL_MACHINE\\SOFTWARE\\test")

Types

RegHandle = distinct Handle
RegValueKind {...}{.size: 4.} = enum
  regNone = 0, regSZ = 1, regExpandSZ = 2, regBinary = 3, regDword = 4, regDwordBE = 5,
  regLink = 6, regMultiSZ = 7, regQword = 11
RegKeyRights {...}{.size: 4.} = enum
  samDefault = 0, samQueryValue = 1, samSetValue = 2, samCreateSubkey = 4,
  samEnumSubkeys = 8, samNotify = 16, samCreateLink = 32, samWow64 = 256, samWow32 = 512,
  samDelete = 65536, samReadControl = 131072, samWrite = 131078, samRead = 131097,
  samWriteDac = 262144, samWriteOwner = 524288, samAll = 983103
represents Windows Registry Key Security and Access Rights values. Security rights inherit from parent keys. Can be combined.
WinString = WideCString
cstring when useWinAscii is declared or WideCString otherwise.
RegistryError = object of Exception
raised when registry-related error occurs.

Consts

HKEY_CLASSES_ROOT: RegHandle = 2147483648
HKEY_CURRENT_USER: RegHandle = 2147483649
HKEY_LOCAL_MACHINE: RegHandle = 2147483650
HKEY_USERS: RegHandle = 2147483651
HKEY_PERFORMANCE_DATA: RegHandle = 2147483652
HKEY_CURRENT_CONFIG: RegHandle = 2147483653
HKEY_DYN_DATA: RegHandle = 2147483654

Procs

proc `==`(x, y: RegHandle): bool {...}{.inline, raises: [], tags: [].}
the == operator for RegHandle.
proc `!=`(x, y: RegHandle): bool {...}{.inline, raises: [], tags: [].}
the != operator for RegHandle
proc `or`(a, b: RegKeyRights): RegKeyRights {...}{.inline, raises: [], tags: [].}
the or operator for RegKeyRights.
proc `|`(a, b: RegKeyRights): RegKeyRights {...}{.inline, raises: [], tags: [].}
alias for or for RegKeyRights.
proc create(handle: RegHandle; subkey: string; samDesired: RegKeyRights): RegHandle {...}{.
    sideEffect, raises: [RegistryError], tags: [].}
creates new subkey. RegistryError is raised if key already exists.
create(HKEY_LOCAL_MACHINE, "Software\\My Soft", samRead or samWrite)
proc create(path: string; samDesired: RegKeyRights): RegHandle {...}{.sideEffect,
    raises: [RegistryError], tags: [].}
creates new subkey. RegistryError is raised if key already exists.
create("HKEY_LOCAL_MACHINE\\Software\\My Soft", samRead or samWrite)
proc createOrOpen(handle: RegHandle; subkey: string; samDesired: RegKeyRights): RegHandle {...}{.
    sideEffect, raises: [RegistryError], tags: [].}
same as create proc, but does not raise RegistryError if key already exists.
createOrOpen(HKEY_LOCAL_MACHINE, "Software", samRead or samWrite)
proc createOrOpen(path: string; samDesired: RegKeyRights): RegHandle {...}{.sideEffect,
    raises: [RegistryError], tags: [].}
same as create proc, but does not raise RegistryError if key already exists.
createOrOpen("HKEY_LOCAL_MACHINE\\Software", samRead or samWrite)
proc open(handle: RegHandle; subkey: string; samDesired: RegKeyRights = samDefault): RegHandle {...}{.
    sideEffect, raises: [RegistryError], tags: [].}
opens the specified registry key. Note that key names are not case sensitive. Raises RegistryError when handle is invalid or subkey does not exist.
open(HKEY_LOCAL_MACHINE, "Software", samRead or samWrite)
proc open(path: string; samDesired: RegKeyRights = samDefault): RegHandle {...}{.sideEffect,
    raises: [RegistryError], tags: [].}
same as open proc, but enables specifying path without using root RegHandle constants.
open("HKEY_LOCAL_MACHINE\\Software", samRead or samWrite)
proc openCurrentUser(samDesired: RegKeyRights = samDefault): RegHandle {...}{.sideEffect,
    raises: [RegistryError], tags: [].}
retrieves a handle to the HKEY_CURRENT_USER key for the user the current thread is impersonating.
proc close(handle: RegHandle) {...}{.sideEffect, raises: [], tags: [].}
closes a registry handle. After using this proc, handle is no longer valid and should not be used with any registry procedures. Try to close registry handles as soon as possible.
var h = open(HKEY_LOCAL_MACHINE, "Software", samRead)
close(h)
proc close(handles: varargs[RegHandle]) {...}{.inline, sideEffect, raises: [], tags: [].}
same as close proc, but allows to close several handles at once.
var h1 = open(HKEY_LOCAL_MACHINE, "Software", samRead)
var h2 = open(HKEY_LOCAL_MACHINE, "Hardware", samRead)
close(h1, h2)
proc countValues(handle: RegHandle): int32 {...}{.sideEffect, raises: [RegistryError],
    tags: [].}
returns number of key-value pairs that are associated with the specified registry key. Does not count default key-value pair. The key must have been opened with the samQueryValue access right.
proc countSubkeys(handle: RegHandle): int32 {...}{.sideEffect, raises: [RegistryError],
    tags: [].}
returns number of subkeys that are contained by the specified registry key. The key must have been opened with the samQueryValue access right.
proc writeString(handle: RegHandle; key, value: string) {...}{.sideEffect,
    raises: [RegistryError], tags: [].}
writes value of type REG_SZ to specified key.
writeString(handle, "hello", "world")
proc writeExpandString(handle: RegHandle; key, value: string) {...}{.sideEffect,
    raises: [RegistryError], tags: [].}
writes value of type REG_EXPAND_SZ to specified key.
proc writeMultiString(handle: RegHandle; key: string; value: openArray[string]) {...}{.
    sideEffect, raises: [RegistryError], tags: [].}
writes value of type REG_MULTI_SZ to specified key. Empty strings are not allowed and being skipped.
proc writeInt32(handle: RegHandle; key: string; value: int32) {...}{.sideEffect,
    raises: [RegistryError], tags: [].}
writes value of type REG_DWORD to specified key.
proc writeInt64(handle: RegHandle; key: string; value: int64) {...}{.sideEffect,
    raises: [RegistryError], tags: [].}
writes value of type REG_QWORD to specified key.
proc writeBinary(handle: RegHandle; key: string; value: openArray[byte]) {...}{.sideEffect,
    raises: [RegistryError], tags: [].}
writes value of type REG_BINARY to specified key.
proc readString(handle: RegHandle; key: string): TaintedString {...}{.sideEffect,
    raises: [Exception, RegistryError], tags: [].}
reads value of type REG_SZ from registry key.
proc readExpandString(handle: RegHandle; key: string): TaintedString {...}{.sideEffect,
    raises: [Exception, RegistryError], tags: [].}
reads value of type REG_EXPAND_SZ from registry key. The key must have been opened with the samQueryValue access right. Use expandEnvString proc to expand environment variables.
proc readMultiString(handle: RegHandle; key: string): seq[string] {...}{.sideEffect,
    raises: [Exception, RegistryError], tags: [].}
reads value of type REG_MULTI_SZ from registry key.
proc readInt32(handle: RegHandle; key: string): int32 {...}{.sideEffect,
    raises: [RegistryError], tags: [].}
reads value of type REG_DWORD from registry key. The key must have been opened with the samQueryValue access right.
proc readInt64(handle: RegHandle; key: string): int64 {...}{.sideEffect,
    raises: [RegistryError], tags: [].}
reads value of type REG_QWORD from registry entry. The key must have been opened with the samQueryValue access right.
proc readBinary(handle: RegHandle; key: string): seq[byte] {...}{.sideEffect,
    raises: [Exception, RegistryError], tags: [].}
reads value of type REG_BINARY from registry entry. The key must have been opened with the samQueryValue access right.
proc delSubkey(handle: RegHandle; subkey: string;
              samDesired: RegKeyRights = samDefault) {...}{.sideEffect,
    raises: [RegistryError], tags: [].}

deletes a subkey and its values from the specified platform-specific view of the registry. Note that key names are not case sensitive. The subkey to be deleted must not have subkeys. To delete a key and all it subkeys, you need to enumerate the subkeys and delete them individually. To delete keys recursively, use the delTree.

samDesired should be samWow32 or samWow64.

proc delTree(handle: RegHandle; subkey: string) {...}{.sideEffect, raises: [RegistryError],
    tags: [].}

deletes the subkeys and values of the specified key recursively. subkey can be nil, in that case, all subkeys of handle is deleted.

The key must have been opened with samDelete, samEnumSubkeys and samQueryValue access rights.

proc expandEnvString(str: string): string {...}{.raises: [Exception], tags: [].}
helper proc to expand strings returned by readExpandString proc. If string cannot be expanded, empty string is returned.
echo expandEnvString("%PATH%") # => C:\Windows;C:\Windows\system32...

Iterators

iterator enumSubkeys(handle: RegHandle): string {...}{.sideEffect,
    raises: [RegistryError, Exception], tags: [].}
enumerates through each subkey of the specified registry key. The key must have been opened with the samQueryValue access right.
iterator enumValueNames(handle: RegHandle): string {...}{.sideEffect,
    raises: [RegistryError, Exception], tags: [].}
enumerates the value names for the specified registry key. The key must have been opened with the samQueryValue access right.