diff --git a/.changes/fix-sidecar-dots.md b/.changes/fix-sidecar-dots.md new file mode 100644 index 0000000000..58f001f80b --- /dev/null +++ b/.changes/fix-sidecar-dots.md @@ -0,0 +1,6 @@ +--- +"shell": patch +"shell-js": patch +--- + +Fix sidecar with dots in the filename not working on Windows. diff --git a/plugins/shell/src/commands.rs b/plugins/shell/src/commands.rs index 5275e9b9c4..0facce7193 100644 --- a/plugins/shell/src/commands.rs +++ b/plugins/shell/src/commands.rs @@ -115,7 +115,12 @@ fn prepare_cmd( let mut command = if options.sidecar { let program = PathBuf::from(program); let program_as_string = program.display().to_string(); - let program_no_ext_as_string = program.with_extension("").display().to_string(); + let has_extension = program.extension().is_some_and(|ext| ext == "exe"); + let program_no_ext_as_string = if has_extension { + program.with_extension("").display().to_string() + } else { + program_as_string.clone() + }; let configured_sidecar = window .config() .bundle diff --git a/plugins/shell/src/process/mod.rs b/plugins/shell/src/process/mod.rs index 44f037b015..1384bbb8bd 100644 --- a/plugins/shell/src/process/mod.rs +++ b/plugins/shell/src/process/mod.rs @@ -118,9 +118,23 @@ pub struct Output { fn relative_command_path(command: &Path) -> crate::Result { match platform::current_exe()?.parent() { #[cfg(windows)] - Some(exe_dir) => Ok(exe_dir.join(command).with_extension("exe")), + Some(exe_dir) => { + let mut command_path = exe_dir.join(command); + let already_exe = command_path.extension().is_some_and(|ext| ext == "exe"); + if !already_exe { + // do not use with_extension to retain dots in the command filename + command_path.as_mut_os_string().push(".exe"); + } + Ok(command_path) + } #[cfg(not(windows))] - Some(exe_dir) => Ok(exe_dir.join(command)), + Some(exe_dir) => { + let mut command_path = exe_dir.join(command); + if command_path.extension().is_some_and(|ext| ext == "exe") { + command_path.set_extension(""); + } + Ok(command_path) + } None => Err(crate::Error::CurrentExeHasNoParent), } } @@ -133,6 +147,10 @@ impl From for StdCommand { impl Command { pub(crate) fn new>(program: S) -> Self { + log::debug!( + "Creating sidecar {}", + program.as_ref().to_str().unwrap_or("") + ); let mut command = StdCommand::new(program); command.stdout(Stdio::piped()); @@ -451,9 +469,33 @@ fn spawn_pipe_reader) -> CommandEvent + Send + Copy + 'static>( // tests for the commands functions. #[cfg(test)] mod tests { - #[cfg(not(windows))] use super::*; + #[test] + fn relative_command_path_resolves() { + let cwd_parent = platform::current_exe() + .unwrap() + .parent() + .unwrap() + .to_owned(); + assert_eq!( + relative_command_path(Path::new("Tauri.Example")).unwrap(), + cwd_parent.join(if cfg!(windows) { + "Tauri.Example.exe" + } else { + "Tauri.Example" + }) + ); + assert_eq!( + relative_command_path(Path::new("Tauri.Example.exe")).unwrap(), + cwd_parent.join(if cfg!(windows) { + "Tauri.Example.exe" + } else { + "Tauri.Example" + }) + ); + } + #[cfg(not(windows))] #[test] fn test_cmd_spawn_output() {