README.md
1winreg
2[![Winreg on Appveyor][appveyor-image]][appveyor]
3[![Winreg on crates.io][cratesio-image]][cratesio]
4[![Winreg on docs.rs][docsrs-image]][docsrs]
5======
6
7[appveyor-image]: https://ci.appveyor.com/api/projects/status/f3lwrt67ghrf5omd?svg=true
8[appveyor]: https://ci.appveyor.com/project/gentoo90/winreg-rs
9[cratesio-image]: https://img.shields.io/crates/v/winreg.svg
10[cratesio]: https://crates.io/crates/winreg
11[docsrs-image]: https://docs.rs/winreg/badge.svg
12[docsrs]: https://docs.rs/winreg
13
14Rust bindings to MS Windows Registry API. Work in progress.
15
16Current features:
17* Basic registry operations:
18 * open/create/delete keys
19 * read and write values
20 * seamless conversion between `REG_*` types and rust primitives
21 * `String` and `OsString` <= `REG_SZ`, `REG_EXPAND_SZ` or `REG_MULTI_SZ`
22 * `String`, `&str` and `OsStr` => `REG_SZ`
23 * `u32` <=> `REG_DWORD`
24 * `u64` <=> `REG_QWORD`
25* Iteration through key names and through values
26* Transactions
27* Transacted serialization of rust types into/from registry (only primitives and structures for now)
28
29## Usage
30
31### Basic usage
32
33```toml
34# Cargo.toml
35[dependencies]
36winreg = "0.6"
37```
38
39```rust
40extern crate winreg;
41use std::io;
42use std::path::Path;
43use winreg::enums::*;
44use winreg::RegKey;
45
46fn main() -> io::Result<()> {
47 println!("Reading some system info...");
48 let hklm = RegKey::predef(HKEY_LOCAL_MACHINE);
49 let cur_ver = hklm.open_subkey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion")?;
50 let pf: String = cur_ver.get_value("ProgramFilesDir")?;
51 let dp: String = cur_ver.get_value("DevicePath")?;
52 println!("ProgramFiles = {}\nDevicePath = {}", pf, dp);
53 let info = cur_ver.query_info()?;
54 println!("info = {:?}", info);
55 let mt = info.get_last_write_time_system();
56 println!(
57 "last_write_time as winapi::um::minwinbase::SYSTEMTIME = {}-{:02}-{:02} {:02}:{:02}:{:02}",
58 mt.wYear, mt.wMonth, mt.wDay, mt.wHour, mt.wMinute, mt.wSecond
59 );
60
61 // enable `chrono` feature on `winreg` to make this work
62 // println!(
63 // "last_write_time as chrono::NaiveDateTime = {}",
64 // info.get_last_write_time_chrono()
65 // );
66
67 println!("And now lets write something...");
68 let hkcu = RegKey::predef(HKEY_CURRENT_USER);
69 let path = Path::new("Software").join("WinregRsExample1");
70 let (key, disp) = hkcu.create_subkey(&path)?;
71
72 match disp {
73 REG_CREATED_NEW_KEY => println!("A new key has been created"),
74 REG_OPENED_EXISTING_KEY => println!("An existing key has been opened"),
75 }
76
77 key.set_value("TestSZ", &"written by Rust")?;
78 let sz_val: String = key.get_value("TestSZ")?;
79 key.delete_value("TestSZ")?;
80 println!("TestSZ = {}", sz_val);
81
82 key.set_value("TestDWORD", &1234567890u32)?;
83 let dword_val: u32 = key.get_value("TestDWORD")?;
84 println!("TestDWORD = {}", dword_val);
85
86 key.set_value("TestQWORD", &1234567891011121314u64)?;
87 let qword_val: u64 = key.get_value("TestQWORD")?;
88 println!("TestQWORD = {}", qword_val);
89
90 key.create_subkey("sub\\key")?;
91 hkcu.delete_subkey_all(&path)?;
92
93 println!("Trying to open nonexistent key...");
94 hkcu.open_subkey(&path).unwrap_or_else(|e| match e.kind() {
95 io::ErrorKind::NotFound => panic!("Key doesn't exist"),
96 io::ErrorKind::PermissionDenied => panic!("Access denied"),
97 _ => panic!("{:?}", e),
98 });
99 Ok(())
100}
101```
102
103### Iterators
104
105```rust
106extern crate winreg;
107use std::io;
108use winreg::RegKey;
109use winreg::enums::*;
110
111fn main() -> io::Result<()> {
112 println!("File extensions, registered in system:");
113 for i in RegKey::predef(HKEY_CLASSES_ROOT)
114 .enum_keys().map(|x| x.unwrap())
115 .filter(|x| x.starts_with("."))
116 {
117 println!("{}", i);
118 }
119
120 let system = RegKey::predef(HKEY_LOCAL_MACHINE)
121 .open_subkey("HARDWARE\\DESCRIPTION\\System")?;
122 for (name, value) in system.enum_values().map(|x| x.unwrap()) {
123 println!("{} = {:?}", name, value);
124 }
125
126 Ok(())
127}
128```
129
130### Transactions
131
132```toml
133# Cargo.toml
134[dependencies]
135winreg = { version = "0.6", features = ["transactions"] }
136```
137
138```rust
139extern crate winreg;
140use std::io;
141use winreg::RegKey;
142use winreg::enums::*;
143use winreg::transaction::Transaction;
144
145fn main() -> io::Result<()> {
146 let t = Transaction::new()?;
147 let hkcu = RegKey::predef(HKEY_CURRENT_USER);
148 let (key, _disp) = hkcu.create_subkey_transacted("Software\\RustTransaction", &t)?;
149 key.set_value("TestQWORD", &1234567891011121314u64)?;
150 key.set_value("TestDWORD", &1234567890u32)?;
151
152 println!("Commit transaction? [y/N]:");
153 let mut input = String::new();
154 io::stdin().read_line(&mut input)?;
155 input = input.trim_right().to_owned();
156 if input == "y" || input == "Y" {
157 t.commit()?;
158 println!("Transaction committed.");
159 }
160 else {
161 // this is optional, if transaction wasn't committed,
162 // it will be rolled back on disposal
163 t.rollback()?;
164
165 println!("Transaction wasn't committed, it will be rolled back.");
166 }
167
168 Ok(())
169}
170```
171
172### Serialization
173
174```toml
175# Cargo.toml
176[dependencies]
177winreg = { version = "0.6", features = ["serialization-serde"] }
178serde = "1"
179serde_derive = "1"
180```
181
182```rust
183#[macro_use]
184extern crate serde_derive;
185extern crate winreg;
186use std::error::Error;
187use winreg::enums::*;
188
189#[derive(Debug, Serialize, Deserialize, PartialEq)]
190struct Coords {
191 x: u32,
192 y: u32,
193}
194
195#[derive(Debug, Serialize, Deserialize, PartialEq)]
196struct Size {
197 w: u32,
198 h: u32,
199}
200
201#[derive(Debug, Serialize, Deserialize, PartialEq)]
202struct Rectangle {
203 coords: Coords,
204 size: Size,
205}
206
207#[derive(Debug, Serialize, Deserialize, PartialEq)]
208struct Test {
209 t_bool: bool,
210 t_u8: u8,
211 t_u16: u16,
212 t_u32: u32,
213 t_u64: u64,
214 t_usize: usize,
215 t_struct: Rectangle,
216 t_string: String,
217 t_i8: i8,
218 t_i16: i16,
219 t_i32: i32,
220 t_i64: i64,
221 t_isize: isize,
222 t_f64: f64,
223 t_f32: f32,
224}
225
226fn main() -> Result<(), Box<Error>> {
227 let hkcu = winreg::RegKey::predef(HKEY_CURRENT_USER);
228 let (key, _disp) = hkcu.create_subkey("Software\\RustEncode")?;
229 let v1 = Test{
230 t_bool: false,
231 t_u8: 127,
232 t_u16: 32768,
233 t_u32: 123456789,
234 t_u64: 123456789101112,
235 t_usize: 1234567891,
236 t_struct: Rectangle{
237 coords: Coords{ x: 55, y: 77 },
238 size: Size{ w: 500, h: 300 },
239 },
240 t_string: "test 123!".to_owned(),
241 t_i8: -123,
242 t_i16: -2049,
243 t_i32: 20100,
244 t_i64: -12345678910,
245 t_isize: -1234567890,
246 t_f64: -0.01,
247 t_f32: 3.14,
248 };
249
250 key.encode(&v1)?;
251
252 let v2: Test = key.decode()?;
253 println!("Decoded {:?}", v2);
254
255 println!("Equal to encoded: {:?}", v1 == v2);
256 Ok(())
257}
258```
259
260## Changelog
261
262### 0.6.2
263
264* Add `RegKey::delete_subkey_with_flags()` ([#27](https://github.com/gentoo90/winreg-rs/pull/27))
265
266### 0.6.1
267
268* Add `last_write_time` field to `RegKeyMetadata` (returned by `RegKey::query_info()`) ([#25](https://github.com/gentoo90/winreg-rs/pull/25)).
269* Add `get_last_write_time_system()` and `get_last_write_time_chrono()` (under `chrono` feature) methods to `RegKeyMetadata`.
270
271### 0.6.0
272
273* Breaking change: `create_subkey`, `create_subkey_with_flags`, `create_subkey_transacted` and
274`create_subkey_transacted_with_flags` now return a tuple which contains the subkey and its disposition
275which can be `REG_CREATED_NEW_KEY` or `REG_OPENED_EXISTING_KEY` ([#21](https://github.com/gentoo90/winreg-rs/issues/21)).
276* Examples fixed to not use `unwrap` according to [Rust API guidelines](https://rust-lang-nursery.github.io/api-guidelines/documentation.html#examples-use--not-try-not-unwrap-c-question-mark).
277
278### 0.5.1
279
280* Reexport `HKEY` ([#15](https://github.com/gentoo90/winreg-rs/issues/15)).
281* Add `raw_handle` method ([#18](https://github.com/gentoo90/winreg-rs/pull/18)).
282
283### 0.5.0
284
285* Breaking change: `open_subkey` now opens a key with readonly permissions.
286Use `create_subkey` or `open_subkey_with_flags` to open with read-write permissins.
287* Breaking change: features `transactions` and `serialization-serde` are now disabled by default.
288* Breaking change: serialization now uses `serde` instead of `rustc-serialize`.
289* `winapi` updated to `0.3`.
290* Documentation fixes ([#14](https://github.com/gentoo90/winreg-rs/pull/14))
291
292### 0.4.0
293
294* Make transactions and serialization otional features
295* Update dependensies + minor fixes ([#12](https://github.com/gentoo90/winreg-rs/pull/12))
296
297### 0.3.5
298
299* Implement `FromRegValue` for `OsString` and `ToRegValue` for `OsStr` ([#8](https://github.com/gentoo90/winreg-rs/issues/8))
300* Minor fixes
301
302### 0.3.4
303
304* Add `copy_tree` method to `RegKey`
305* Now checked with [rust-clippy](https://github.com/Manishearth/rust-clippy)
306 * no more `unwrap`s
307 * replaced `to_string` with `to_owned`
308* Fix: reading strings longer than 2048 characters ([#6](https://github.com/gentoo90/winreg-rs/pull/6))
309
310### 0.3.3
311
312* Fix: now able to read values longer than 2048 bytes ([#3](https://github.com/gentoo90/winreg-rs/pull/3))
313
314### 0.3.2
315
316* Fix: `FromRegValue` trait now requires `Sized` (fixes build with rust 1.4)
317
318### 0.3.1
319
320* Fix: bump `winapi` version to fix build
321
322### 0.3.0
323
324* Add transactions support and make serialization transacted
325* Breaking change: use `std::io::{Error,Result}` instead of own `RegError` and `RegResult`
326