[client] run as admin

This commit is contained in:
ddidderr 2025-03-20 22:34:34 +01:00
parent 78f7ff2405
commit d69cf115c8
Signed by: ddidderr
GPG Key ID: 3841F1C27E6F0E14
2 changed files with 58 additions and 25 deletions

View File

@ -39,7 +39,12 @@ tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] } tracing-subscriber = { version = "0.3", features = ["env-filter"] }
uuid = { version = "1", features = ["v7"] } uuid = { version = "1", features = ["v7"] }
walkdir = "2" walkdir = "2"
windows = { version = "0.61" } windows = { version = "0.61", features = [
"Win32",
"Win32_UI",
"Win32_UI_Shell",
"Win32_UI_WindowsAndMessaging",
] }
[profile.release] [profile.release]
debug = true debug = true

View File

@ -1,8 +1,5 @@
#[cfg(target_os = "windows")]
use std::os::windows::ffi::OsStrExt;
use std::{ use std::{
collections::HashSet, collections::HashSet,
fs::File,
net::SocketAddr, net::SocketAddr,
path::{Path, PathBuf}, path::{Path, PathBuf},
sync::Arc, sync::Arc,
@ -58,27 +55,33 @@ fn install_game(id: String, state: tauri::State<LanSpreadState>) -> bool {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
fn run_as_admin(file: &str, params: &str, dir: &str) -> bool { fn run_as_admin(file: &str, params: &str, dir: &str) -> bool {
todo!(); use std::{ffi::OsStr, os::windows::ffi::OsStrExt};
use windows::{Win32::UI::Shell::ShellExecuteW, core::PCWSTR};
let file_wide: Vec<u16> = OsStr::new(file).encode_wide().chain(Some(0)).collect(); let file_wide: Vec<u16> = OsStr::new(file).encode_wide().chain(Some(0)).collect();
let params_wide: Vec<u16> = OsStr::new(params).encode_wide().chain(Some(0)).collect(); let params_wide: Vec<u16> = OsStr::new(params).encode_wide().chain(Some(0)).collect();
let dir_wide: Vec<u16> = OsStr::new(dir).encode_wide().chain(Some(0)).collect(); let dir_wide: Vec<u16> = OsStr::new(dir).encode_wide().chain(Some(0)).collect();
let runas_wide: Vec<u16> = OsStr::new("runas").encode_wide().chain(Some(0)).collect();
let result = unsafe { let result = unsafe {
ShellExecuteW( ShellExecuteW(
HWND(0), None,
Some("runas"), PCWSTR::from_raw(runas_wide.as_ptr()),
&file_wide, PCWSTR::from_raw(file_wide.as_ptr()),
Some(&params_wide), PCWSTR::from_raw(params_wide.as_ptr()),
Some(&dir_wide), PCWSTR::from_raw(dir_wide.as_ptr()),
windows::Win32::UI::WindowsAndMessaging::SW_SHOWNORMAL, windows::Win32::UI::WindowsAndMessaging::SW_SHOWNORMAL,
) )
}; };
result.0 > 32 // Success if greater than 32 (result.0 as usize) > 32 // Success if greater than 32
} }
#[tauri::command] #[cfg(target_os = "windows")]
fn run_game(id: String, state: tauri::State<LanSpreadState>) { fn run_game_windows(id: String, state: tauri::State<LanSpreadState>) {
use std::fs::File;
const FIRST_START_DONE_FILE: &str = ".softlan_first_start_done"; const FIRST_START_DONE_FILE: &str = ".softlan_first_start_done";
let games_folder = let games_folder =
@ -90,34 +93,59 @@ fn run_game(id: String, state: tauri::State<LanSpreadState>) {
return; return;
} }
let game_path = games_folder.join(id); let game_path = games_folder.join(id.clone());
let game_setup_bin = game_path.join("game_setup.cmd"); let game_setup_bin = game_path.join("game_setup.cmd");
let game_start_bin = game_path.join("game_start.cmd"); let game_start_bin = game_path.join("game_start.cmd");
let first_start_done_file = game_path.join(FIRST_START_DONE_FILE); let first_start_done_file = game_path.join(FIRST_START_DONE_FILE);
if !first_start_done_file.exists() && game_setup_bin.exists() { if !first_start_done_file.exists() && game_setup_bin.exists() {
if let Err(e) = std::process::Command::new(game_setup_bin) let result = run_as_admin(
.current_dir(&game_path) "cmd.exe",
.spawn() &format!(
{ r#"/c "{} local {} de playername""#,
log::error!("failed to run game_setup.cmd: {e}"); game_setup_bin.display(),
&id
),
&game_path.display().to_string(),
);
if !result {
log::error!("failed to run game_setup.cmd");
return; return;
} else if let Err(e) = File::create(FIRST_START_DONE_FILE) { }
if let Err(e) = File::create(&first_start_done_file) {
log::error!("failed to create {first_start_done_file:?}: {e}"); log::error!("failed to create {first_start_done_file:?}: {e}");
} }
} }
if game_start_bin.exists() { if game_start_bin.exists() {
if let Err(e) = std::process::Command::new(game_start_bin) let result = run_as_admin(
.current_dir(&game_path) "cmd.exe",
.spawn() &format!(
{ r#"/c "{} local {} de playername""#,
log::error!("failed to run game_start.cmd: {e}"); game_start_bin.display(),
&id
),
&game_path.display().to_string(),
);
if !result {
log::error!("failed to run game_start.cmd");
} }
} }
} }
#[tauri::command]
fn run_game(id: String, state: tauri::State<LanSpreadState>) {
#[cfg(target_os = "windows")]
run_game_windows(id, state);
#[cfg(not(target_os = "windows"))]
log::error!("run_game not implemented for this platform: id={id}, state={state:?}");
}
fn set_game_install_state_from_path(game_db: &mut GameDB, path: &Path, installed: bool) { fn set_game_install_state_from_path(game_db: &mut GameDB, path: &Path, installed: bool) {
if let Some(file_name) = path.file_name() { if let Some(file_name) = path.file_name() {
if let Some(file_name) = file_name.to_str() { if let Some(file_name) = file_name.to_str() {