reggie

package module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 19, 2025 License: MIT Imports: 8 Imported by: 0

README

reggie

Go Reference

A clean, zero dependency wrapper around Go's golang.org/x/sys/windows/registry package.


Features

  • Effortlessly open, create, edit, or delete keys with guards in place

  • JSON exports at the object level. Export any registry key object as structured, readable JSON — perfect for API's, dumping, etc.

  • Seamlessly walk through registry hierarchies using a depth-first pattern.

  • Dynamically create values with automatic type enforcement and correct constraints.

  • Easily fetch all key-value pairs from any key in one call.

  • Retrieve typed values easily without boilerplate.

  • Clone a key object in memory, (including all values and subkeys) without affecting the original — useful for testing or state comparisons.


Examples

Since v1.0.0 there are more features you can utilise.

For example, if you want to expose registry information over an API, you can export the data sets to JSON:

func main() {
	key, err := reggie.OpenKey(registry.CURRENT_USER, `Control Panel\Accessibility`, registry.ALL_ACCESS)
	if err != nil {
		log.Fatal(err)
	}
	defer key.Close()

	_ = key.DeepLoad() // There are 3 different load functions. Check the docs.

	json, err := key.ExportJson() // Built in functions to convert the data structure into a JSON compatible format
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(string(json))
}

Maybe you want to apply your own logic while walking through the registry:

func main() {
	key, err := reggie.OpenKey(registry.CURRENT_USER, `Software`, registry.READ)
	if err != nil {
		log.Fatalf("Failed to open root key: %v", err)
	}
	defer key.Close()

	key.DeepLoad() // DeepLoad first if you want an easy traversal. Optionally write your own parameters in the walk function

	err = key.Walk(func(k *reggie.Key) error {
		fmt.Printf("Path: %s\n", k.Path)

		for name, value := range k.Values {
			fmt.Printf("- Key %s: Value: %v\n", name, value)
		}

		return nil
	})

	if err != nil {
		log.Fatalf("Walk failed: %v", err)
	}
}

Reggie aims to be as close to the original usage as possible while expanding on it. Let's take the usual way of creating a value inside a key with the registry pkg:

func main() {
	key, err := registry.OpenKey(registry.CURRENT_USER, `Software`, registry.ALL_ACCESS)
	if err != nil {
		log.Fatal(err)
	}

	err = key.SetBinaryValue("name", []byte("value"))
	if err != nil {
		log.Fatal(err)
	}

	err = key.SetQWordValue("name", 64)
	if err != nil {
		log.fatal(err)
	}
	... 
}

It can be cumbersome setting values like this. Instead, we have a helper function CreateValue(...). The function will obtain the underlying type and process it accordingly. As a result, types can be custom:

type QWORD uint64

func main() {
	reggieDemo, err := reggie.OpenKey(registry.CURRENT_USER, `Software\ReggieDemo`, registry.ALL_ACCESS)
	if err != nil {
		log.Fatal(err)
	}
	defer reggieDemo.Close()

	var val QWORD

	val = 12345

	err = reggieDemo.CreateValue("string key", val)
	if err != nil {
		log.Fatal(err)
	}
}

See the examples folder for more.

Contributing & License

Contributions are absolutely welcome. There is definitely improvements to be made and bugs unknown at present, so if you wish to contribute please check the contributing markdown.

License is MIT, so you can take this and do whatever you want with it!

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func KeyExists added in v1.0.1

func KeyExists(key registry.Key, path string) bool

KeyExists checks if a registry key exists at the given path and root. It returns true if the key exists and can be opened, false otherwise.

Types

type Key added in v1.0.1

type Key struct {
	Handle     registry.Key       // Parent registry key
	RootKey    registry.Key       // The top-most level key, e.g. HKCU, HKLM
	Path       string             // Path of the parent registry key
	Subkeys    map[string]*SubKey // Map of subkeys from the opened registry key
	Values     map[string]any     // Values inside the parent registry key
	Permission uint32             // Permission used for the key
	Loaded     bool               // Represents if the key has had its values / subkeys loaded
}

Represents a registry key layout

func OpenKey added in v1.0.1

func OpenKey(root registry.Key, path string, access uint32) (*Key, error)

Opens an existing registry key.

func (*Key) CloneKey added in v1.0.1

func (k *Key) CloneKey() (*Key, error)

Performs a deep in memory copy of current key and returns it

func (*Key) Close added in v1.0.1

func (k *Key) Close() error

Close closes the key

func (*Key) CreateKey added in v1.0.1

func (k *Key) CreateKey(path string, access uint32) (*Key, error)

Creates a new key. This function will error if the key already exists, unlike the std package version where it will silently open regardless. Enforces correctness and guards.

func (*Key) CreateValue added in v1.0.1

func (k *Key) CreateValue(key string, value any) error

Creates a value in accordance with the std registry package constraints. Underlying value type is reflected. Supports all known types of values.

func (*Key) CreateValueMany added in v1.0.1

func (k *Key) CreateValueMany(data map[string]any) error

Loops through the provided map and calls CreateValue(...) to create all key=>values in the current key object.

func (*Key) DeepLoad added in v1.0.1

func (k *Key) DeepLoad() error

Recursively loads the current key and all of its descendant subkeys. It calls Load() on the current key if it has not been loaded yet, then traverses all loaded subkeys and attempts to load each child key recursively.

func (*Key) DeleteKey added in v1.0.1

func (k *Key) DeleteKey(path string) error

Checks if the key exists and deletes it. Will return an error if the key does not exist. Do not use this on keys that have subkeys. For this, use DeleteKeysAll()

func (*Key) DeleteValue added in v1.0.1

func (k *Key) DeleteValue(name string) error

Safely checks if the value exists and deletes it.

func (*Key) ExportJson added in v1.0.1

func (k *Key) ExportJson() ([]byte, error)

Marshals the current key object into JSON.

func (*Key) GetValue added in v1.0.1

func (k *Key) GetValue(name string) (any, error)

Obtains a value from the key `name`. It will get any type from the registry without needing to specify the specific registry.GetXValue(...) functions.

func (*Key) GetValueAndNames added in v1.0.1

func (k *Key) GetValueAndNames() (map[string]any, error)

Obtains all key=>value pairs from the specified key

func (*Key) Load added in v1.0.1

func (k *Key) Load() error

Calls LoadWithLimit(0) for an explicit way to load keys with no limit.

func (*Key) LoadWithLimit added in v1.0.1

func (k *Key) LoadWithLimit(limit int) error

Will get the current key you have opened and then enumerate it for futher subkeys and it's children. `limit` is an integer to specify if you want to only load x amount of items, not to be confused with loading x amount of keys inside keys from the current key. LoadWithLimit will only do a shallow read one level down. If you want full, recursive deep loading see DeepLoad

func (*Key) Walk added in v1.0.1

func (k *Key) Walk(fn func(k *Key) error) error

Recursively traverses the key and all of its loaded subkeys from the top down, applying the provided function `fn` to each *Key in depth-first order.

If the key has not been loaded yet, Walk will call Load() automatically to populate subkeys before continuing traversal.

If fn returns an error at any point, Walk stops immediately and returns that error.

func (*Key) WalkReverse added in v1.0.1

func (k *Key) WalkReverse(fn func(k *Key) error) error

Recursively traverses the key and all of its loaded subkeys in bottom up post order. Uses the same logic as Walk()

type SubKey

type SubKey struct {
	Name   string         // Name of the subkey
	Values map[string]any // Values inside the subkey
	Child  *Key           // Child keys inside the subkey
}

Represents a registry subkey layout

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL