diff --git a/Cargo.toml b/Cargo.toml index 6fa13cd..898d04b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,7 +39,12 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } uuid = { version = "1", features = ["v7"] } walkdir = "2" -windows = { version = "0.61" } +windows = { version = "0.61", features = [ + "Win32", + "Win32_UI", + "Win32_UI_Shell", + "Win32_UI_WindowsAndMessaging", +] } [profile.release] debug = true diff --git a/crates/lanspread-tauri-deno-ts/src-tauri/src/lib.rs b/crates/lanspread-tauri-deno-ts/src-tauri/src/lib.rs index 6007ee4..5558811 100644 --- a/crates/lanspread-tauri-deno-ts/src-tauri/src/lib.rs +++ b/crates/lanspread-tauri-deno-ts/src-tauri/src/lib.rs @@ -1,8 +1,5 @@ -#[cfg(target_os = "windows")] -use std::os::windows::ffi::OsStrExt; use std::{ collections::HashSet, - fs::File, net::SocketAddr, path::{Path, PathBuf}, sync::Arc, @@ -58,27 +55,33 @@ fn install_game(id: String, state: tauri::State) -> bool { #[cfg(target_os = "windows")] 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 = OsStr::new(file).encode_wide().chain(Some(0)).collect(); let params_wide: Vec = OsStr::new(params).encode_wide().chain(Some(0)).collect(); let dir_wide: Vec = OsStr::new(dir).encode_wide().chain(Some(0)).collect(); + let runas_wide: Vec = OsStr::new("runas").encode_wide().chain(Some(0)).collect(); let result = unsafe { ShellExecuteW( - HWND(0), - Some("runas"), - &file_wide, - Some(¶ms_wide), - Some(&dir_wide), + None, + PCWSTR::from_raw(runas_wide.as_ptr()), + PCWSTR::from_raw(file_wide.as_ptr()), + PCWSTR::from_raw(params_wide.as_ptr()), + PCWSTR::from_raw(dir_wide.as_ptr()), 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] -fn run_game(id: String, state: tauri::State) { +#[cfg(target_os = "windows")] +fn run_game_windows(id: String, state: tauri::State) { + use std::fs::File; + const FIRST_START_DONE_FILE: &str = ".softlan_first_start_done"; let games_folder = @@ -90,34 +93,59 @@ fn run_game(id: String, state: tauri::State) { 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_start_bin = game_path.join("game_start.cmd"); let first_start_done_file = game_path.join(FIRST_START_DONE_FILE); if !first_start_done_file.exists() && game_setup_bin.exists() { - if let Err(e) = std::process::Command::new(game_setup_bin) - .current_dir(&game_path) - .spawn() - { - log::error!("failed to run game_setup.cmd: {e}"); + let result = run_as_admin( + "cmd.exe", + &format!( + r#"/c "{} local {} de playername""#, + game_setup_bin.display(), + &id + ), + &game_path.display().to_string(), + ); + + if !result { + log::error!("failed to run game_setup.cmd"); 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}"); } } if game_start_bin.exists() { - if let Err(e) = std::process::Command::new(game_start_bin) - .current_dir(&game_path) - .spawn() - { - log::error!("failed to run game_start.cmd: {e}"); + let result = run_as_admin( + "cmd.exe", + &format!( + r#"/c "{} local {} de playername""#, + 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) { + #[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) { if let Some(file_name) = path.file_name() { if let Some(file_name) = file_name.to_str() {