plugins-workspace icon indicating copy to clipboard operation
plugins-workspace copied to clipboard

Expose the ability to get the path of a sidecar binary at runtime

Open tlentz opened this issue 2 years ago • 14 comments

Describe the problem

In my case, I have 2 binaries that I need to include as sidecars (with the platform triple). One of these binaries depends on the other and needs the path to the binary passed in through the environment, but today there is no way to get the path to a sidecar binary at runtime.

Describe the solution you'd like

I would like to be able to do something like so:

let sidecarOne = Command.sidecar("program-one", ...);
let sidecarOnePath = sidecarOne.getPath();

let sidecarTwo = Command.sidecar("program-two", [...args], { env: { PROGRAM_ONE_PATH: sidecarOnePath } });

Alternatives considered

No response

Additional context

No response

tlentz avatar May 26 '23 16:05 tlentz

@tlentz I was in need for the same thing, I ended up creating a copy of the internal function found here:

fn relative_command_path(command: String) -> Result<String> {
  match platform::current_exe()?.parent() {
    #[cfg(windows)]
    Some(exe_dir) => Ok(format!("{}\\{command}.exe", exe_dir.display())),
    #[cfg(not(windows))]
    Some(exe_dir) => Ok(format!("{}/{command}", exe_dir.display())),
    None => Err(Error::Command("Could not evaluate executable dir".to_string()).into()),
  }
}

Gamote avatar Mar 30 '24 14:03 Gamote

This is something I need as well. I want to call the bundled binary directly using my own wrapper rather than executing with the shell plugin sidecar.

JokerQyou avatar Nov 08 '24 16:11 JokerQyou

I would also like the flexibility run a binary as a sidecar that's inside a folder placed in the file system with bundle.resources in tauri.conf.json.

I use bundle.resources to install a folder of dependencies for a pystinaller compiled python executable. (one-directory mode, because it's faster than one-file mode) The executable needs to be located next to the dependencies folder, and it needs to run as a sidecar.

sansseriff avatar Dec 05 '24 01:12 sansseriff

That probably only works on Windows because linux and macos have more strict package layouts (tho tbh i'm not sure how much it's enforced), but aside from that why does it have to run as a sidecar? What's advantage over a regular Command?

FabianLars avatar Dec 05 '24 09:12 FabianLars

That probably only works on Windows because linux and macos have more strict package layouts (tho tbh i'm not sure how much it's enforced), but aside from that why does it have to run as a sidecar? What's advantage over a regular Command?

  • Bundle external tools for user so the Tauri app won't have to ask user to install them and bother to locate them.
  • Use wrapper libraries specifically built for external tools instead of regular Command execution, for example, to parse realtime progress from stdout, or answer interactive selection via stdout+stdin.

JokerQyou avatar Dec 05 '24 15:12 JokerQyou

That probably only works on Windows because linux and macos have more strict package layouts (tho tbh i'm not sure how much it's enforced), but aside from that why does it have to run as a sidecar? What's advantage over a regular Command?

I don't know, can I just use a regular command? How would I do that? I just need to start a webserver executable at tauri runtime, and kill it when tauri is closed. Here's my rough layout as far as what I'd like to connect with what.

[tauri (exec)] <--need to be same directory? --> [python (sidecar exec)] <--must be same directory--> [python deps (folder)]

my tauri.conf.json: https://github.com/bkorzh/dbay/blob/main/software/frontend/src-tauri/tauri.conf.json

my main.rs: https://github.com/bkorzh/dbay/blob/main/software/frontend/src-tauri/src/main.rs

To get it working on linux currently, I'm using the linux.deb.files feature. Which puts a folder of dependencies in usr/bin/ which probably isn't kosher in some way.

sansseriff avatar Dec 05 '24 22:12 sansseriff

Bundle external tools for user so the Tauri app won't have to ask user to install them and bother to locate them.

bunding != execution. you can bundle something as a sidecar via externalBin but still use the normal Command api to start them. The sidecar api is really just a helper to get the path right.

Use wrapper libraries specifically built for external tools instead of regular Command execution, for example, to parse realtime progress from stdout, or answer interactive selection via stdout+stdin.

This makes no sense tbh, especially in context of my question. The execution of a Command and a sidecar is exactly the same.

FabianLars avatar Dec 05 '24 22:12 FabianLars

I don't know, can I just use a regular command?

yes (i mean, otherwise this request wouldn't make as much sense)

How would I do that? I just need to start a webserver executable at tauri runtime, and kill it when tauri is closed.

If it's bundled as a resource you can use the resolve_resource api to get the path, then pipe that into tauri's Command api (if you want it to be autoclosed) or rust's std Command (if you're okay with killing it yourself).

To get it working on linux currently, I'm using the linux.deb.files feature. Which puts a folder of dependencies in usr/bin/ which probably isn't kosher in some way.

Don't let any linux package/repo maintainer hear that 😂 (srsly, this is basically a no-go and won't be accepted in any distro repos - i wonder if any distros actually have some kind of preventation for this or if it's just a standard)

FabianLars avatar Dec 05 '24 22:12 FabianLars

Yeah the linux.deb.files feature has the potential to be a real big footgun.

I barely know rust, so I've tried all sorts of stuff to get a functioning .deb just with tauri.conf.json customization.

sansseriff avatar Dec 05 '24 22:12 sansseriff

This is something i really wanna look into (and wanted to for ages). Do you know by any chance how pyinstaller apps look for their files? Do only check the cwd (that would be awful), some predefined paths, some env vars (for paths)?

FabianLars avatar Dec 05 '24 22:12 FabianLars

By default yes, only cwd is supported. Though there seems to be workarounds that I didn't want to spend time figuring out.

https://stackoverflow.com/a/72725639

I agree, disappointing there isn't an established method.

sansseriff avatar Dec 05 '24 22:12 sansseriff

Bundle external tools for user so the Tauri app won't have to ask user to install them and bother to locate them.

bunding != execution. you can bundle something as a sidecar via externalBin but still use the normal Command api to start them. The sidecar api is really just a helper to get the path right.

That's the point - title of this issue is literally about "get the path of a sidecar binary at runtime" - it's about getting the path right, not about execution. (The execution part is my further explanation to "why I want to get the path rather than just execute the binary using normal Command".)

Per the Tauri doc:

You may need to embed external binaries to add additional functionality to your application or prevent users from installing additional dependencies (e.g., Node.js or Python). We call this binary a sidecar.

So it's not nonsense that I would want to bundle a binary and get its path using sidecar API.

Use wrapper libraries specifically built for external tools instead of regular Command execution, for example, to parse realtime progress from stdout, or answer interactive selection via stdout+stdin.

This makes no sense tbh, especially in context of my question. The execution of a Command and a sidecar is exactly the same.

Of course if you'd run the binary using sidecar then it's the same. But I just want to get path to the binary using sidecar API instead of running it using Command. Because the wrapper only cares about path of the binary.

Tauri doc also states that you can bundle resources and get path of them at runtime. But IIRC resources are not recommended way to bundle binary executables - correct my if I'm wrong - I only see the sidecar doc talking about binary files.

JokerQyou avatar Dec 06 '24 08:12 JokerQyou

I'm sorry but i think the context here is completely wrong. My question you reacted to initially was specifically for this comment not yours before or the issue as a whole.

there i asked why it has to be run as a sidecar instead of a command (which again, is literally the same). I was never "against" bundling something as a sidecar or the api requested here.

FabianLars avatar Dec 06 '24 09:12 FabianLars

This is also something I am running into right now. I like the way the sidecar feature can handle bundling for me on different platforms by resolving through the filenames, but I want to run the sidecar binary through my own wrapper, which is not possible at the moment. I have resorted to using the Resources feature, with different config files for different platforms.

Krulknul avatar Aug 10 '25 17:08 Krulknul