Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OpenOptions to windows-registry #3461

Merged
merged 5 commits into from
Jan 22, 2025
Merged

Add OpenOptions to windows-registry #3461

merged 5 commits into from
Jan 22, 2025

Conversation

kennykerr
Copy link
Collaborator

Rather than adding more registry creation methods to satisfy #3269, #3346, or any future needs, this update introduces an OpenOptions type modeled after std::fs::OpenOptions. This new type provides the options and flags that you can set in order to configure how a registry key is opened. The Key type continues to provide the create and open methods as a convenience but internally they now also use OpenOptions for construction. Let's consider a few examples.

Today you can use create to create or open a registry key for read and write access:

let path = "software\\windows-rs\\sample";
let key = CURRENT_USER.create(path)?;

What if you only want to open the key if it already exists? Well you can use open instead but it offers only read access:

let key = CURRENT_USER.open(path)?;

This is where you can use the new options method to gain more control:

let key = CURRENT_USER.options().write(true).open(path)?;

key.set_u32("name", 123)?;

This opens the subkey with write access but only if it already exists. The call will fail if the key does not exist. Want to create the key in all cases? Just set the create option:

let key = CURRENT_USER.options().create(true).write(true).open(path)?;

You can also optionally create a Transaction object for transactional access to the registry:

let tx = Transaction::new()?;

let key = CURRENT_USER
    .options()
    .read(true)
    .write(true)
    .create(true)
    .transaction(&tx)
    .open(path)?;

key.set_u32("name", 123)?;

tx.commit()?;

Failure to commit the transaction will cause all changes to be rolled back when the transaction object is dropped. They are also not observable outside of the transaction until and unless commit is called.

Finally, I removed the Default implementation from the Key object. This just seemed confusing as you could try (and fail) to use the various registry functions on an invalid registry key handle. If for some reason you need to hold on to an invalid registry key you can still use the unsafe from_raw method.

Fixes: #3269
Fixes: #3346

@Nerixyz
Copy link
Contributor

Nerixyz commented Jan 22, 2025

You can also optionally create a Transaction object for transactional access to the registry:

This example would be great in the README (so it shows up in the crate documentation on docs.rs).

@kennykerr
Copy link
Collaborator Author

Done - thanks for the suggestion!

ChrisDenton
ChrisDenton previously approved these changes Jan 22, 2025
Copy link
Collaborator

@ChrisDenton ChrisDenton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a really nice API! The extensibility is a nice feature too as it'll make future feature requests much easier to accommodate.

@kennykerr
Copy link
Collaborator Author

@riverar - good feedback but I'd rather not add features opportunistically. If and when such needs present themselves, we can now more easily introduce them.

Co-authored-by: Rafael Rivera <[email protected]>
@kennykerr kennykerr merged commit e5c8f82 into master Jan 22, 2025
78 checks passed
@kennykerr kennykerr deleted the registry-options branch January 22, 2025 21:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add new method to windows_registry::Key open_mut() Suggest windows-registry can support transactions.
4 participants