#Best Practice for Capturing Path From "Open With"

1 messages · Page 1 of 1 (latest)

candid pagoda
#

Hello there! This may end up being an obvious question, perhaps due to my 101-tier Rust knowledge, but so far I am seriously struggling in my search through GH Issues / Documentation.

Problem Statement: When my tauri app is assigned to handle files of a specific extension, I want to be able to capture the path of the file which has been interacted with (via either "Open With" or double-click) to open my app and pass it to front-end components for further use.

Thus far, researching native file handling has been very difficult. Issues #918 and #3736 discuss the topic of file association, and briefly touch on app ingestion of a file path as some sort of CLI argument, but both of these threads are old and vague(?) with respect to actually capturing a path and then passing it to the frontend.

What is the current best practice to actually obtain and successfully forward the path of a file which is the subject of an "Open With" interaction on Windows? (Or, alternatively, double-clicked on when the tauri app has been successfully registered as a handler of that file's extension.)

Thank you for any and all guidance on this issue.

mortal grotto
#

Am i understanding it correctly that the file association is out of the question / already working?

candid pagoda
mortal grotto
#

Okay fair enough

#

So the way file associations and similar things like deep links (basically file assocs but urls) work on windows is that each time those "events" are invoked they will spawn a new instance of your app with the path/url as a CLI arg - not tauri's doing, that's the OS itself.

To get that cli arg you usually use https://doc.rust-lang.org/std/env/fn.args.html.

If you don't want it to spawn multiple instances then you can use https://github.com/tauri-apps/plugins-workspace/tree/v1/plugins/single-instance (swap to v2 branch for tauri v2)

#

To send that cli arg you have a few options. In the single-instance handler you usually use https://tauri.app/v1/guides/features/events/ though window.eval works too if you have a js handler in global scope (we recommend events either way).

If there was no running instance, and the assoc spawns your app using an event probably won't work as it will have timing issues. You could create a command https://tauri.app/v1/guides/features/command that requests the initial arg, use the afforemention window.eval to set a var on the global js window var, or if you spawn your app's window in rust you could use https://docs.rs/tauri/latest/tauri/window/struct.WindowBuilder.html#method.initialization_script to do the same.

candid pagoda
mortal grotto
#

yep

#

or not quite

#

if you use a command you don't need the global window

#

you can use a normal return value of the command

#

so basically const args = await invoke("get_args"); gives you the list of cli args

#

sure, if it makes it easier to re-use later, feel free to set it on the global window then

candid pagoda
#

Oh, fantastic! That's a lot more straightforward than I would have thought. It shouldn't need to be very re-usable since it's effectively a one-time, on-start check, after which everything gets passed to the app's normal processes.

#

I will give this a shot over lunch and post working code in the event that everything shakes out like it should, then ideally mark this as resolved.

#

(And, to break my own oath here, is pre-tauri-2.0 file association still the responsibility of a custom .msi setup via msi.wxs?)

mortal grotto
#

yes

#

or custom .nsi thingy for setup.exe for the nsis installer introduced in 1.3 in case you use that

candid pagoda
#

Good to know. I appreciate it!

candid pagoda
candid pagoda
#

Okay, I went and used a mixture of both my dev version and running tauri build --debug to check my app post-installation, and the provided solution is indeed correct.

#

As mentioned previously, I am awful at Rust. This was the function I arrived at:

#[tauri::command]
async fn get_args() -> Vec<String> {
  let mut arg_list = vec![];
  for arg in env::args() {
    arg_list.push(arg);
  }
  return arg_list;
}
#

To be excessively clear, this goes in your main.rs, and then you add it to the main() function's invoke handler list like so: .invoke_handler(tauri::generate_handler![get_args])