How to make my .exe autorun in Windows?

I've tried to write it in Registry with winreg, but I've got "Access Denied" error

Which register key did you try to write? If it is in HKEY_LOCAL_MACHINE you must run it as administrator.

It was HKEY_CURRENT_USER

Where exactly did you try to write?

HKEY_CURRENT_USER\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run

Did you also use those double backslash in the command you used? You should only use a single one. A double backslash is only necessary to escape the backslash when using C/C++ or Rust to write to the registry.

Yes, I use it in code too.

In code the \ after HKEY_CURRENT_USER also needs to be doubled.

Oh, my bad, my path in Rust is actually HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run

You probably want to use raw strings, like this:

let key = r#"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"#;

No need for double-backslashes that way.

2 Likes

Thanks, will try it!

Thanks! Solution is this code:

use std::path::Path;
use winreg::enums::*;
use winreg::RegKey;

fn main() {
    let key = r#"HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run"#;
    let hkcu = RegKey::predef(HKEY_CURRENT_USER);
    let path = Path::new("Software").join("Microsoft").join("Windows").join("CurrentVersion").join("Run");
    let (key, disp) = hkcu.create_subkey(&path).unwrap();
    dbg!(&disp);
    key.set_value("Path", &"written by Rust").unwrap();
}
1 Like

Are registry paths actual Paths in the Rust sense?

I often run into this with URL paths which certainly are not, but with the registry being deeply embedded into the OS maybe registry paths are?

Huh, interesting questions. Well it is a Windows path. The root is omitted when using registry APIs but the full NT path would be:

\Registry\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run

For the most part, the current Path API simply assumes all paths are bytes separated by one or more platform specific separator. So registry paths do fit that bill, with or without the root.

However, conceptually Path is meant to represent a file path. That is, something you use with the platform's file APIs. So in that sense it's technically wrong to use path for anything else even if it works at the moment.

If Rust ever gets proper handling of Win32 file paths, it's possible that using it for the registry could have unexpected results. But then again, Rust has pretty strong backwards compatibility guarantees for the std.

In short, it's probably wrong but it works for the most part.

But it's example from winreg docs

Sure. But technically winreg is wrong to use it in the example because a win32 file path is not used the same as a registry path (i.e. the APIs to use them are entirely separate).

But as I said it should work for joining paths and is without the hassle of making a new type. So how much this bothers you is up to you.

winreg actually uses AsRef<OsStr> which Path implements.

Which is great. But the example shows using Path. Which is what it is.