The knot solve :)

Hello,

fuuh i have some knots in my brain what's up rust:). I have following Problem with crate winreg:

let hklm = winreg::RegKey::predef(HKEY_LOCAL_MACHINE);
let key = hklm.open_subkey(r#"SOFTWARE\WOW6432Node\SomeNode"#).unwrap(); 

(yes i know i overwrite the error handling with and unwrap:))

for i in key.enum_keys() {
    let z = i.unwrap();
    {
        println!("{}", z);
        let subkey = hklm.open_subkey("SOFTWARE\\WOW6432Node\\SomeNode\\Games\\".to_owned()+&z).unwrap();
        // Snipets Below
    }
}

My first try was to use an enum iterator like in the doc-api:

    for (name, value) in subkey.enum_values().map(|x| x.unwrap())
    {
        	println!("{} = {:?}", name, value);
    }

But my problem is that i cannot get value as an string an use {} intead of {:?} for testing. How can i get value as an String?

An then i have thinked that i use only the tupel name

    for (name) in subkey.enum_values() {
        println!("{:?}", name.unwrap());
    }

And yes name.0 was an String but name.1 was the same problem like value:).

I want only iterate over an key in the win registry and match the names and values and do some file operations on that match. I hope someone can solve this knot. Is a hard way in rust and sorry that i ignore the whole error handling with an simple unwrap(). I love unwrap, its make some things easier in small programs:).

Thx

Do you mean format! ?

Here is an example with many annotated types:

use ::winreg::{ // v 0.6.0
    enums::HKEY_LOCAL_MACHINE,
    RegKey,
    RegValue,
};

fn main ()
{
    let hklm: RegKey = RegKey::predef(HKEY_LOCAL_MACHINE);
    let games: RegKey = hklm.open_subkey(
        r"SOFTWARE\WOW6432Node\SomeNode\Games"
    ).unwrap();
    for subkey_name in games.enum_keys().map(Result::unwrap) {
        let _: String = subkey_name;
        dbg!(&subkey_name);
        let subkey: RegKey = games.open_subkey(
            format!(r"Games\{}", subkey_name)
        ).unwrap();
        for (name, value) in subkey.enum_values().map(Result::unwrap) {
            let _: String = name;
            let _: RegValue = value;
            let s: String = format!("{} = {:?}", name, value);
            dbg!(&s);
            // you can use `s: String` here
        }
    }
}

Using unwrap() with a final application, especially when fast prototyping, is indeed fine. However, sooner or later it won't be, so using error handling, even if it is just using the ? operator, is a good habit :slight_smile:

use ::std::{
   io,
};
use ::winreg::{ // v 0.6.0
   enums::HKEY_LOCAL_MACHINE,
   RegKey,
   RegValue,
};

/// Since `main` can return a Result, let's do it.
/// In practice, the behavior will be very close to `unwrap`, but it leads to better coding habits
fn main () -> Result<(), io::Error>
{
   let hklm: RegKey = RegKey::predef(HKEY_LOCAL_MACHINE);
   let games: RegKey = hklm.open_subkey(
       r"SOFTWARE\WOW6432Node\SomeNode\Games"
   )?; // it is often as easy as replacing `.unwrap` with `?`
   for subkey_name_res in games.enum_keys() {
       let subkey_name: String = subkey_name_res?;
       dbg!(&subkey_name);
       let subkey: RegKey = games.open_subkey(
           format!(r"Games\{}", subkey_name)
       )?;
       for result in subkey.enum_values() {
           let (name, value): (String, RegValue) = result?;
           let s: String = format!("{} = {:?}", name, value);
           dbg!(&s);
           // you can use `s: String` here
       }
   }
   Ok(()) // and let's not forget to wrap the (success) return value with `Ok`
}

@Yandros
Thank you, now my next hours are on my computer and code some rust code:).
And thx for the comments, they very valueable.

@Yandros
A little additional question: How can i split the variable value2 into his parts or i mean how can i access the raw string to deliver it to the format?

let value2: String = format!("{:?}",value);

//RegValue(REG_SZ: "neutral")
//[src\main.rs:28] &value2 = "RegValue(REG_SZ: \"german\")"

At the moment i must think in an array:). Here we have an index and i don't know how i can access this index. To receive the second index with the string.

thx
@Yandros
Edit: There are 2 fields one bytes and vtype? Are the bytes-field the raw return from registy and a constructor automatic convert it to an RegValue????

The API of the crate is indeed not very intuitive, I think that you may be looking for:

use ::winreg::types::FromRegValue;

let value2 = String::from_reg_value(value).unwrap();
1 Like

@Yandros perfectly:)
Yes the API is for RUst-Pros that inhale all rust specific things. Rust is so special in a few things:) and my fault is to compare it with php and c. In the future i must learn that some grounded procedure i must abandoned in the future and i became that what Rust promise: fast, reliable and secure programs:).

1 Like

@Yandros

can i ask you some other question? You know the winreg-crate;).

The String that i receive is a escaped string, how can i the string deescape?

I mean when i write it back escape with \ is wonderful but when i will use a path from registry i need the path only with \ for the filesystem.

Edit: The file system from rust accept without problems the returned escaped string.

I don't think the String was escaped, it was just displayed escaped when printed with the {:?} formatting (e.g., the formatting that dbg! uses):

1 Like

@Yandros Yes my fault , i have in the past all printed in debug output and after your solution i have forget that i can output an real string.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.