Hi guys, how do I trigger a new process to be run as admin using Rust?
I'm not really the expert on this, but it's 2am so my speed of response hopefully makes up for that I might be wrong.
I think it inherits permissions from the parent process, so if you want rust to spawn a process as admin then you just need to run the rust executable as admin.
The same as using any other language - with OS-specific functions.
Assuming this is Windows and you’re trying to run a program as admin from a normal program, the easiest API is ShellExecuteW
with the "runas"
action. With Microsoft’s Windows API for Rust, this would be something like:
mod bindings {
windows::include_bindings!();
}
use bindings::Windows::Win32::System::SystemServices::PWSTR;
use bindings::Windows::Win32::UI::Shell::ShellExecuteW;
use bindings::Windows::Win32::UI::WindowsAndMessaging::HWND;
fn main() {
windows::initialize_sta().unwrap();
let r = unsafe { ShellExecuteW(HWND::NULL, "runas", "C:\\Windows\\System32\\cmd.exe", PWSTR::NULL, PWSTR::NULL, 1) };
if r.0 < 32 {
println!("error: {:?}", r);
}
}
Erm, I think you may want to UTF-16 encode and null terminate those strings?
windows-rs
is very clever. In this case, the parameter has the type IntoParam<'_, PWSTR>
, and there is an implementation of this for &str
that does the UTF-16 encoding and null-termination, collects the result into a Vec<u16>
, converts that to a Box<[u16]>
and passes that as a pointer to the Windows API.
impl<'a> ::windows::IntoParam<'a, PWSTR> for &'a str {
fn into_param(self) -> ::windows::Param<'a, PWSTR> {
::windows::Param::Boxed(PWSTR(::std::boxed::Box::<[u16]>::into_raw(
self.encode_utf16()
.chain(::std::iter::once(0))
.collect::<std::vec::Vec<u16>>()
.into_boxed_slice(),
) as _))
}
}
Oh great, that is useful!
Hey mate, what library am I importing because it fails to build.
I get the following errors:
error[E0433]: failed to resolve: could not find `Windows` in `bindings`
--> src\main.rs:6:15
|
6 | use bindings::Windows::Win32::System::SystemServices::PWSTR;
| ^^^^^^^ could not find `Windows` in `bindings`
error[E0433]: failed to resolve: could not find `Windows` in `bindings`
--> src\main.rs:7:15
|
7 | use bindings::Windows::Win32::UI::Shell::ShellExecuteW;
| ^^^^^^^ could not find `Windows` in `bindings`
error[E0433]: failed to resolve: could not find `Windows` in `bindings`
--> src\main.rs:8:15
|
8 | use bindings::Windows::Win32::UI::WindowsAndMessaging::HWND;
| ^^^^^^^ could not find `Windows` in `bindings`
error[E0433]: failed to resolve: use of undeclared crate or module `windows`
--> src\main.rs:3:5
|
3 | windows::include_bindings!();
| ^^^^^^^ use of undeclared crate or module `windows`
error[E0433]: failed to resolve: use of undeclared crate or module `windows`
--> src\main.rs:12:5
|
12 | windows::initialize_sta().unwrap();
| ^^^^^^^ use of undeclared crate or module `windows`
error[E0433]: failed to resolve: use of undeclared type `HWND`
--> src\main.rs:13:36
|
13 | let r = unsafe { ShellExecuteW(HWND::NULL, "runas", "C:\\Windows\\System32\\cmd.exe", PWSTR::NULL, PWSTR::NULL, 1) };
| ^^^^ use of undeclared type `HWND`
error[E0433]: failed to resolve: use of undeclared type `PWSTR`
--> src\main.rs:13:91
|
13 | let r = unsafe { ShellExecuteW(HWND::NULL, "runas", "C:\\Windows\\System32\\cmd.exe", PWSTR::NULL, PWSTR::NULL, 1) };
| ^^^^^ use of undeclared type `PWSTR`
error[E0433]: failed to resolve: use of undeclared type `PWSTR`
--> src\main.rs:13:104
|
13 | let r = unsafe { ShellExecuteW(HWND::NULL, "runas", "C:\\Windows\\System32\\cmd.exe", PWSTR::NULL, PWSTR::NULL, 1) };
| ^^^^^ use of undeclared type `PWSTR`
error[E0425]: cannot find function, tuple struct or tuple variant `ShellExecuteW` in this scope
--> src\main.rs:13:22
|
13 | let r = unsafe { ShellExecuteW(HWND::NULL, "runas", "C:\\Windows\\System32\\cmd.exe", PWSTR::NULL, PWSTR::NULL, 1) };
| ^^^^^^^^^^^^^ not found in this scope
error: aborting due to 9 previous errors
Some errors have detailed explanations: E0425, E0433.
For more information about an error, try `rustc --explain E0425`.
error: could not compile `learning`
To learn more, run the command again with --verbose.
after using your code:
mod bindings {
windows::include_bindings!();
}
use bindings::Windows::Win32::System::SystemServices::PWSTR;
use bindings::Windows::Win32::UI::Shell::ShellExecuteW;
use bindings::Windows::Win32::UI::WindowsAndMessaging::HWND;
fn main() {
windows::initialize_sta().unwrap();
let r = unsafe { ShellExecuteW(HWND::NULL, "runas", "C:\\Windows\\System32\\cmd.exe", PWSTR::NULL, PWSTR::NULL, 1) };
if r.0 < 32 {
println!("error: {:?}", r);
}
}
I left out a bit of the setup that’s described at GitHub - microsoft/windows-rs: Rust for Windows. You need to add the dependencies to Cargo.toml
, as both normal and build dependencies:
[dependencies]
windows = "0.10.0"
[build-dependencies]
windows = "0.10.0"
and you need a build.rs
in the same directory as Cargo.toml
which will generate the APIs:
fn main() {
windows::build!(
Windows::Win32::UI::Shell::ShellExecuteW
);
}
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.