@@ -423,35 +423,118 @@ fn start_backend_server(
423423 let exe_path = std:: env:: current_exe ( ) . ok ( ) ;
424424 let exe_dir = exe_path. as_ref ( ) . and_then ( |p| p. parent ( ) ) ;
425425
426- let mut possible_exe_paths: Vec < PathBuf > = vec ! [
427- backend_path. join( "dist" ) . join( "backend-server.exe" ) ,
428- backend_path. join( "dist" ) . join( "backend-server" ) ,
429- ] ;
426+ // Build list of possible executable paths, prioritizing platform-specific executables
427+ let mut possible_exe_paths: Vec < PathBuf > = vec ! [ ] ;
428+
429+ // Platform-specific executable names (check platform-specific first)
430+ #[ cfg( windows) ]
431+ {
432+ possible_exe_paths. push ( backend_path. join ( "dist" ) . join ( "backend-server.exe" ) ) ;
433+ possible_exe_paths. push ( backend_path. join ( "dist" ) . join ( "backend-server" ) ) ;
434+ }
435+
436+ #[ cfg( not( windows) ) ]
437+ {
438+ possible_exe_paths. push ( backend_path. join ( "dist" ) . join ( "backend-server" ) ) ;
439+ possible_exe_paths. push ( backend_path. join ( "dist" ) . join ( "backend-server.exe" ) ) ;
440+ }
430441
431442 // Try Tauri resource resolution (for bundled resources)
432443 if let Ok ( resource_dir) = app. path ( ) . resource_dir ( ) {
433- possible_exe_paths. push ( resource_dir. join ( "backend-server.exe" ) ) ;
434- possible_exe_paths. push ( resource_dir. join ( "backend-server" ) ) ;
444+ #[ cfg( windows) ]
445+ {
446+ possible_exe_paths. push ( resource_dir. join ( "backend-server.exe" ) ) ;
447+ possible_exe_paths. push ( resource_dir. join ( "backend-server" ) ) ;
448+ }
449+ #[ cfg( not( windows) ) ]
450+ {
451+ possible_exe_paths. push ( resource_dir. join ( "backend-server" ) ) ;
452+ possible_exe_paths. push ( resource_dir. join ( "backend-server.exe" ) ) ;
453+ }
435454 }
436455
437456 // Add paths relative to executable (fallback)
438457 if let Some ( exe_dir) = exe_dir {
439- possible_exe_paths. push ( exe_dir. join ( "backend-server.exe" ) ) ;
440- possible_exe_paths. push ( exe_dir. join ( "backend-server" ) ) ;
441- possible_exe_paths. push ( exe_dir. join ( "resources" ) . join ( "backend-server.exe" ) ) ;
442- possible_exe_paths. push ( exe_dir. join ( "resources" ) . join ( "backend-server" ) ) ;
458+ #[ cfg( windows) ]
459+ {
460+ possible_exe_paths. push ( exe_dir. join ( "backend-server.exe" ) ) ;
461+ possible_exe_paths. push ( exe_dir. join ( "backend-server" ) ) ;
462+ possible_exe_paths. push ( exe_dir. join ( "resources" ) . join ( "backend-server.exe" ) ) ;
463+ possible_exe_paths. push ( exe_dir. join ( "resources" ) . join ( "backend-server" ) ) ;
464+ }
465+ #[ cfg( not( windows) ) ]
466+ {
467+ possible_exe_paths. push ( exe_dir. join ( "backend-server" ) ) ;
468+ possible_exe_paths. push ( exe_dir. join ( "backend-server.exe" ) ) ;
469+ possible_exe_paths. push ( exe_dir. join ( "resources" ) . join ( "backend-server" ) ) ;
470+ possible_exe_paths. push ( exe_dir. join ( "resources" ) . join ( "backend-server.exe" ) ) ;
471+ }
472+
443473 // Also check parent directories (for nested bundle structures)
444474 if let Some ( parent) = exe_dir. parent ( ) {
445- possible_exe_paths. push ( parent. join ( "backend-server.exe" ) ) ;
446- possible_exe_paths. push ( parent. join ( "backend-server" ) ) ;
475+ #[ cfg( windows) ]
476+ {
477+ possible_exe_paths. push ( parent. join ( "backend-server.exe" ) ) ;
478+ possible_exe_paths. push ( parent. join ( "backend-server" ) ) ;
479+ }
480+ #[ cfg( not( windows) ) ]
481+ {
482+ possible_exe_paths. push ( parent. join ( "backend-server" ) ) ;
483+ possible_exe_paths. push ( parent. join ( "backend-server.exe" ) ) ;
484+ }
447485 }
448486 }
449487
450- let backend_exe = possible_exe_paths. iter ( ) . find ( |p| p. exists ( ) ) . cloned ( ) ;
488+ // Find the first existing executable, filtering out placeholders (very small files)
489+ let backend_exe = possible_exe_paths. iter ( ) . find ( |p| {
490+ if !p. exists ( ) {
491+ return false ;
492+ }
493+
494+ // On non-Windows, skip .exe files (they're Windows executables)
495+ #[ cfg( not( windows) ) ]
496+ {
497+ if p. file_name ( ) . and_then ( |n| n. to_str ( ) ) . map ( |s| s. ends_with ( ".exe" ) ) . unwrap_or ( false ) {
498+ return false ;
499+ }
500+ }
501+
502+ // Filter out placeholder files (very small files < 1KB are likely placeholders)
503+ if let Ok ( metadata) = std:: fs:: metadata ( p) {
504+ let size = metadata. len ( ) ;
505+ if size < 1024 {
506+ warn ! ( "Skipping potential placeholder file: {:?} (size: {} bytes)" , p, size) ;
507+ return false ;
508+ }
509+ }
510+
511+ true
512+ } ) . cloned ( ) ;
451513
452514 if let Some ( exe_path) = backend_exe {
453515 info ! ( "Found bundled backend executable: {:?}" , exe_path) ;
454516
517+ // On Unix systems, ensure the executable has execute permissions
518+ #[ cfg( not( windows) ) ]
519+ {
520+ use std:: os:: unix:: fs:: PermissionsExt ;
521+ if let Ok ( metadata) = std:: fs:: metadata ( & exe_path) {
522+ let mut perms = metadata. permissions ( ) ;
523+ let mode = perms. mode ( ) ;
524+ // Check if execute bit is set for owner, group, or others
525+ if mode & 0o111 == 0 {
526+ warn ! ( "Backend executable does not have execute permissions, attempting to fix..." ) ;
527+ perms. set_mode ( mode | 0o111 ) ; // Add execute permissions for all
528+ if let Err ( e) = std:: fs:: set_permissions ( & exe_path, perms) {
529+ error ! ( "Failed to set execute permissions on backend executable: {}" , e) ;
530+ return Err ( format ! ( "Backend executable at {:?} does not have execute permissions and could not be fixed: {}" , exe_path, e) . into ( ) ) ;
531+ } else {
532+ info ! ( "Successfully set execute permissions on backend executable" ) ;
533+ }
534+ }
535+ }
536+ }
537+
455538 // Run migrations in background
456539 let exe_path_clone = exe_path. clone ( ) ;
457540 let db_path_clone = db_path. clone ( ) ;
@@ -848,6 +931,41 @@ pub fn run() {
848931
849932 let mut possible_exe_paths: Vec < PathBuf > = vec ! [ ] ;
850933
934+ // First, check backend/dist directory (development build location)
935+ // Try to find the project root by going up from executable directory
936+ let mut check_backend_dist = |base_dir : & std:: path:: Path | {
937+ // Try various relative paths to find backend/dist
938+ let candidates = vec ! [
939+ base_dir. join( "backend" ) . join( "dist" ) ,
940+ base_dir. join( ".." ) . join( "backend" ) . join( "dist" ) ,
941+ base_dir. join( "../.." ) . join( "backend" ) . join( "dist" ) ,
942+ base_dir. join( "../../.." ) . join( "backend" ) . join( "dist" ) ,
943+ base_dir. join( "../../../.." ) . join( "backend" ) . join( "dist" ) ,
944+ ] ;
945+
946+ for backend_dist in candidates {
947+ let backend_dist = backend_dist. canonicalize ( ) . unwrap_or ( backend_dist) ;
948+ #[ cfg( windows) ]
949+ {
950+ possible_exe_paths. push ( backend_dist. join ( "backend-server.exe" ) ) ;
951+ possible_exe_paths. push ( backend_dist. join ( "backend-server" ) ) ;
952+ }
953+ #[ cfg( not( windows) ) ]
954+ {
955+ possible_exe_paths. push ( backend_dist. join ( "backend-server" ) ) ;
956+ possible_exe_paths. push ( backend_dist. join ( "backend-server.exe" ) ) ;
957+ }
958+ }
959+ } ;
960+
961+ // Check from executable directory
962+ check_backend_dist ( exe_dir) ;
963+
964+ // Also check from current working directory (for development)
965+ if let Ok ( current_dir) = std:: env:: current_dir ( ) {
966+ check_backend_dist ( & current_dir) ;
967+ }
968+
851969 // Try Tauri resource resolution (for bundled resources)
852970 match app_handle. path ( ) . resource_dir ( ) {
853971 Ok ( resource_dir) => {
@@ -863,8 +981,17 @@ pub fn run() {
863981 } else {
864982 warn ! ( "Resource directory does not exist: {:?}" , resource_dir) ;
865983 }
866- possible_exe_paths. push ( resource_dir. join ( "backend-server.exe" ) ) ;
867- possible_exe_paths. push ( resource_dir. join ( "backend-server" ) ) ;
984+ // Prioritize platform-specific executables
985+ #[ cfg( windows) ]
986+ {
987+ possible_exe_paths. push ( resource_dir. join ( "backend-server.exe" ) ) ;
988+ possible_exe_paths. push ( resource_dir. join ( "backend-server" ) ) ;
989+ }
990+ #[ cfg( not( windows) ) ]
991+ {
992+ possible_exe_paths. push ( resource_dir. join ( "backend-server" ) ) ;
993+ possible_exe_paths. push ( resource_dir. join ( "backend-server.exe" ) ) ;
994+ }
868995 }
869996 Err ( e) => {
870997 warn ! ( "Could not resolve resource directory: {}" , e) ;
@@ -874,13 +1001,24 @@ pub fn run() {
8741001 // Also try resolving the resource directly using Tauri's resolve method
8751002 // This might work better in some bundle configurations
8761003 // Note: In Tauri v2, resolve might work differently, so we try both approaches
877- if let Ok ( resource_path) = app_handle. path ( ) . resolve ( "backend-server" , tauri:: path:: BaseDirectory :: Resource ) {
878- info ! ( "Resolved resource path (backend-server): {:?}" , resource_path) ;
879- possible_exe_paths. push ( resource_path) ;
1004+ // Prioritize platform-specific executables
1005+ #[ cfg( not( windows) ) ]
1006+ {
1007+ if let Ok ( resource_path) = app_handle. path ( ) . resolve ( "backend-server" , tauri:: path:: BaseDirectory :: Resource ) {
1008+ info ! ( "Resolved resource path (backend-server): {:?}" , resource_path) ;
1009+ possible_exe_paths. push ( resource_path) ;
1010+ }
8801011 }
881- if let Ok ( resource_path) = app_handle. path ( ) . resolve ( "backend-server.exe" , tauri:: path:: BaseDirectory :: Resource ) {
882- info ! ( "Resolved resource path (backend-server.exe): {:?}" , resource_path) ;
883- possible_exe_paths. push ( resource_path) ;
1012+ #[ cfg( windows) ]
1013+ {
1014+ if let Ok ( resource_path) = app_handle. path ( ) . resolve ( "backend-server.exe" , tauri:: path:: BaseDirectory :: Resource ) {
1015+ info ! ( "Resolved resource path (backend-server.exe): {:?}" , resource_path) ;
1016+ possible_exe_paths. push ( resource_path) ;
1017+ }
1018+ if let Ok ( resource_path) = app_handle. path ( ) . resolve ( "backend-server" , tauri:: path:: BaseDirectory :: Resource ) {
1019+ info ! ( "Resolved resource path (backend-server): {:?}" , resource_path) ;
1020+ possible_exe_paths. push ( resource_path) ;
1021+ }
8841022 }
8851023
8861024 // For Linux AppImages, resources might be in a different location
@@ -911,10 +1049,21 @@ pub fn run() {
9111049
9121050 // Add paths relative to executable (fallback)
9131051 // For standalone binaries, resources might be next to the executable
914- possible_exe_paths. push ( exe_dir. join ( "backend-server.exe" ) ) ;
915- possible_exe_paths. push ( exe_dir. join ( "backend-server" ) ) ;
916- possible_exe_paths. push ( exe_dir. join ( "resources" ) . join ( "backend-server.exe" ) ) ;
917- possible_exe_paths. push ( exe_dir. join ( "resources" ) . join ( "backend-server" ) ) ;
1052+ // Prioritize platform-specific executables
1053+ #[ cfg( windows) ]
1054+ {
1055+ possible_exe_paths. push ( exe_dir. join ( "backend-server.exe" ) ) ;
1056+ possible_exe_paths. push ( exe_dir. join ( "backend-server" ) ) ;
1057+ possible_exe_paths. push ( exe_dir. join ( "resources" ) . join ( "backend-server.exe" ) ) ;
1058+ possible_exe_paths. push ( exe_dir. join ( "resources" ) . join ( "backend-server" ) ) ;
1059+ }
1060+ #[ cfg( not( windows) ) ]
1061+ {
1062+ possible_exe_paths. push ( exe_dir. join ( "backend-server" ) ) ;
1063+ possible_exe_paths. push ( exe_dir. join ( "backend-server.exe" ) ) ;
1064+ possible_exe_paths. push ( exe_dir. join ( "resources" ) . join ( "backend-server" ) ) ;
1065+ possible_exe_paths. push ( exe_dir. join ( "resources" ) . join ( "backend-server.exe" ) ) ;
1066+ }
9181067
9191068 // For Linux, also check lib and share directories relative to executable
9201069 // This is common for Linux applications and standalone binaries
@@ -928,10 +1077,20 @@ pub fn run() {
9281077
9291078 // Also check parent directories (for nested bundle structures)
9301079 if let Some ( parent) = exe_dir. parent ( ) {
931- possible_exe_paths. push ( parent. join ( "backend-server.exe" ) ) ;
932- possible_exe_paths. push ( parent. join ( "backend-server" ) ) ;
933- possible_exe_paths. push ( parent. join ( "resources" ) . join ( "backend-server.exe" ) ) ;
934- possible_exe_paths. push ( parent. join ( "resources" ) . join ( "backend-server" ) ) ;
1080+ #[ cfg( windows) ]
1081+ {
1082+ possible_exe_paths. push ( parent. join ( "backend-server.exe" ) ) ;
1083+ possible_exe_paths. push ( parent. join ( "backend-server" ) ) ;
1084+ possible_exe_paths. push ( parent. join ( "resources" ) . join ( "backend-server.exe" ) ) ;
1085+ possible_exe_paths. push ( parent. join ( "resources" ) . join ( "backend-server" ) ) ;
1086+ }
1087+ #[ cfg( not( windows) ) ]
1088+ {
1089+ possible_exe_paths. push ( parent. join ( "backend-server" ) ) ;
1090+ possible_exe_paths. push ( parent. join ( "backend-server.exe" ) ) ;
1091+ possible_exe_paths. push ( parent. join ( "resources" ) . join ( "backend-server" ) ) ;
1092+ possible_exe_paths. push ( parent. join ( "resources" ) . join ( "backend-server.exe" ) ) ;
1093+ }
9351094
9361095 #[ cfg( target_os = "linux" ) ]
9371096 {
@@ -947,7 +1106,31 @@ pub fn run() {
9471106 info ! ( " {:?} - {}" , path, if exists { "EXISTS" } else { "not found" } ) ;
9481107 }
9491108
950- let bundled_exe = possible_exe_paths. iter ( ) . find ( |p| p. exists ( ) ) . cloned ( ) ;
1109+ // Find the first existing executable, filtering out placeholders and platform-incompatible files
1110+ let bundled_exe = possible_exe_paths. iter ( ) . find ( |p| {
1111+ if !p. exists ( ) {
1112+ return false ;
1113+ }
1114+
1115+ // On non-Windows, skip .exe files (they're Windows executables)
1116+ #[ cfg( not( windows) ) ]
1117+ {
1118+ if p. file_name ( ) . and_then ( |n| n. to_str ( ) ) . map ( |s| s. ends_with ( ".exe" ) ) . unwrap_or ( false ) {
1119+ return false ;
1120+ }
1121+ }
1122+
1123+ // Filter out placeholder files (very small files < 1KB are likely placeholders)
1124+ if let Ok ( metadata) = std:: fs:: metadata ( p) {
1125+ let size = metadata. len ( ) ;
1126+ if size < 1024 {
1127+ warn ! ( "Skipping potential placeholder file: {:?} (size: {} bytes)" , p, size) ;
1128+ return false ;
1129+ }
1130+ }
1131+
1132+ true
1133+ } ) . cloned ( ) ;
9511134
9521135 // If bundled executable found, use it directly
9531136 if let Some ( exe_path) = bundled_exe {
0 commit comments