@@ -7,7 +7,7 @@ use std::{
77 ffi:: { OsStr , OsString } ,
88 fs, io,
99 path:: { Path , PathBuf } ,
10- process:: Command ,
10+ process:: { Command , Stdio } ,
1111 time:: { SystemTime , UNIX_EPOCH } ,
1212} ;
1313use tauri:: { AppHandle , Manager } ;
@@ -670,6 +670,23 @@ fn run_command(program: &str, args: &[&str], cwd: Option<&Path>) -> Result<Strin
670670 }
671671}
672672
673+ fn spawn_detached ( program : & Path , args : & [ & str ] ) -> Result < ( ) , String > {
674+ let mut command = Command :: new ( program) ;
675+ command
676+ . args ( args)
677+ . stdin ( Stdio :: null ( ) )
678+ . stdout ( Stdio :: null ( ) )
679+ . stderr ( Stdio :: null ( ) ) ;
680+ hide_subprocess_window ( & mut command) ;
681+ if let Some ( path) = command_path_env ( ) {
682+ command. env ( "PATH" , path) ;
683+ }
684+ command
685+ . spawn ( )
686+ . map ( |_| ( ) )
687+ . map_err ( |err| format ! ( "Failed to launch {}: {err}" , program. display( ) ) )
688+ }
689+
673690fn tool_status ( name : & str , version_args : & [ & str ] ) -> ToolStatus {
674691 match run_command ( name, version_args, None ) {
675692 Ok ( output) => ToolStatus {
@@ -833,6 +850,78 @@ fn find_existing_vesktop_state() -> Option<PathBuf> {
833850 . find ( |path| path. exists ( ) )
834851}
835852
853+ #[ cfg( target_os = "windows" ) ]
854+ fn vesktop_executable_candidates ( ) -> Vec < PathBuf > {
855+ let mut candidates = Vec :: new ( ) ;
856+
857+ if let Ok ( local_appdata) = env:: var ( "LOCALAPPDATA" ) {
858+ let local_appdata = PathBuf :: from ( local_appdata) ;
859+ for install_dir in [
860+ local_appdata. join ( "Programs" ) . join ( "vesktop" ) ,
861+ local_appdata. join ( "Programs" ) . join ( "Vesktop" ) ,
862+ local_appdata. join ( "vesktop" ) ,
863+ local_appdata. join ( "Vesktop" ) ,
864+ ] {
865+ candidates. push ( install_dir. join ( "vesktop.exe" ) ) ;
866+ candidates. push ( install_dir. join ( "Vesktop.exe" ) ) ;
867+ }
868+ }
869+
870+ if let Ok ( program_files) = env:: var ( "ProgramFiles" ) {
871+ for install_dir in [
872+ PathBuf :: from ( & program_files) . join ( "Vesktop" ) ,
873+ PathBuf :: from ( program_files) . join ( "vesktop" ) ,
874+ ] {
875+ candidates. push ( install_dir. join ( "vesktop.exe" ) ) ;
876+ candidates. push ( install_dir. join ( "Vesktop.exe" ) ) ;
877+ }
878+ }
879+
880+ candidates. extend (
881+ [ "vesktop" , "Vesktop" ]
882+ . into_iter ( )
883+ . filter_map ( resolve_program) ,
884+ ) ;
885+ candidates
886+ }
887+
888+ #[ cfg( target_os = "linux" ) ]
889+ fn vesktop_executable_candidates ( ) -> Vec < PathBuf > {
890+ [ "vesktop" , "Vesktop" ]
891+ . into_iter ( )
892+ . filter_map ( resolve_program)
893+ . collect ( )
894+ }
895+
896+ #[ cfg( not( any( target_os = "linux" , target_os = "windows" ) ) ) ]
897+ fn vesktop_executable_candidates ( ) -> Vec < PathBuf > {
898+ Vec :: new ( )
899+ }
900+
901+ fn launch_vesktop ( state_path : & Path ) -> Result < String , String > {
902+ for candidate in vesktop_executable_candidates ( ) {
903+ if candidate. is_file ( ) {
904+ spawn_detached ( & candidate, & [ ] ) ?;
905+ return Ok ( format ! ( "Launched {}" , candidate. display( ) ) ) ;
906+ }
907+ }
908+
909+ #[ cfg( target_os = "linux" ) ]
910+ {
911+ let flatpak_state = state_path
912+ . components ( )
913+ . any ( |component| component. as_os_str ( ) == "dev.vencord.Vesktop" ) ;
914+ if flatpak_state {
915+ if let Some ( flatpak) = resolve_program ( "flatpak" ) {
916+ spawn_detached ( & flatpak, & [ "run" , "dev.vencord.Vesktop" ] ) ?;
917+ return Ok ( "Launched Flatpak app dev.vencord.Vesktop" . to_string ( ) ) ;
918+ }
919+ }
920+ }
921+
922+ Err ( "Could not find a Vesktop executable to launch. Apply succeeded, but start Vesktop manually." . to_string ( ) )
923+ }
924+
836925#[ cfg( target_os = "windows" ) ]
837926fn startup_command ( ) -> Result < String , String > {
838927 let exe = env:: current_exe ( )
@@ -1333,6 +1422,30 @@ fn apply_to_vesktop(app: AppHandle, request: ApplyRequest) -> Result<CommandResu
13331422 } )
13341423}
13351424
1425+ #[ tauri:: command]
1426+ fn run_patched_vesktop ( app : AppHandle , request : ApplyRequest ) -> Result < CommandResult , String > {
1427+ let state_path = request
1428+ . state_path
1429+ . as_ref ( )
1430+ . filter ( |path| !path. trim ( ) . is_empty ( ) )
1431+ . map ( PathBuf :: from)
1432+ . or_else ( find_existing_vesktop_state)
1433+ . ok_or_else ( || "Could not locate Vesktop state.json. Set VESKTOP_STATE_FILE or paste the path in the UI." . to_string ( ) ) ?;
1434+ let apply_result = apply_to_vesktop (
1435+ app,
1436+ ApplyRequest {
1437+ state_path : Some ( state_path. display ( ) . to_string ( ) ) ,
1438+ } ,
1439+ ) ?;
1440+ let launch_log = launch_vesktop ( & state_path) ?;
1441+
1442+ Ok ( CommandResult {
1443+ ok : true ,
1444+ message : "Patched Vesktop build was applied and Vesktop was launched." . to_string ( ) ,
1445+ log : format ! ( "{}\n {launch_log}" , apply_result. log) ,
1446+ } )
1447+ }
1448+
13361449#[ cfg_attr( mobile, tauri:: mobile_entry_point) ]
13371450pub fn run ( ) {
13381451 tauri:: Builder :: default ( )
@@ -1348,7 +1461,8 @@ pub fn run() {
13481461 check_updates,
13491462 run_startup_check,
13501463 build_vencord,
1351- apply_to_vesktop
1464+ apply_to_vesktop,
1465+ run_patched_vesktop
13521466 ] )
13531467 . run ( tauri:: generate_context!( ) )
13541468 . expect ( "error while running veskforge" ) ;
0 commit comments