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