【Tauri2.0教程(十一)】让APP关联文件格式右键打开

说明

APP右键打开文件,即如下图所示: 当鼠标在相应文件(比如图片)上面右键的时候,可以在打开方式中关联到我们自己开发的应用,进一步也可以将该程序设置为默认打开程序,但是后者是操作系统的行为,这里不赘述。本文主要讲如何将使用tauri开发的APP关联到对应格式的文件上面,使得在文件上右键的时候能够找到我们开发的应用程序。

配置

tauri.conf.json文件中添加如下配置,其中ext为必填项,表示为哪些格式的文件添加右键打开方式,description表示右键菜单显示什么名称。还有其他一些可选配置,这里不做介绍,需要可以自行查阅官方文档

json 复制代码
"bundle":{
    "fileAssociations": [
      {
        "description": "sharpify",
        "ext": [
          "jpg",
          "jpeg",
          "png"
        ]
      }
    ]
}

上述配置完成以后,将程序进行打包,在jpg、jpeg、png三种图片格式的文件上右键以后,就可以看到已经能够关联我们开发的APP了。

但是还没结束。

虽然已经关联右键菜单了,但是触发右键菜单的行为现在还没有需要我们自己实现。

实现逻辑比较简单,在后端main函数,tauri构建的时候,在setup()函数里面可以得到需要打开的文件全路径,代码如下:

rust 复制代码
fn main() {
    tauri::Builder::default()
        .setup(|app| {
            let args: Vec<String> = std::env::args().collect();
            for arg in args {
                if arg.ends_with(".jpg") || arg.ends_with(".png") {
                    // 我们右键文件的路径名称
                    println!(arg)
                }
            }
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}

如果需要将文件在前端展示的话,就需要涉及跟前端交互的动作,总体来说有两种思路:

  • 当后端(rust)获取图片以后,使用app.emit('open-image', arg)的方式,向前端(vue)发送信息,前端监听该事件
  • 后端获取到要打开的文件路径以后,先存储起来,等前端就绪以后,主动调用后端获取需要的内容

思路一

第一种思路看起来更合理一些,拿到结果以后,主动向前端推送。但是有个问题,这种推送-监听的方式容易丢失数据,比如如果后端先准备好了,他使用emit推送数据了,但是前端并没有准备好,等准备好以后再listen,这时候数据已经不存在了,就无法监听到了。

部分代码如下:

rust 复制代码
fn main() {
    tauri::Builder::default()
        .setup(|app| {
            // 将路径传给前端 Vue 
            log::info!("emit args:{}", &arg); 
                match window.emit_str("open-image", arg) { 
                Ok(_) => log::info!("arg emit successful "), 
                Err(e) => log::error!("something wrong {}", e) 
            }
            Ok(())
        })
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
js 复制代码
onMounted(async () => {
 // 前端通过listen监听后端数据
  fileAssociationUnListen = await listen("open-image", event => {
    filePath.value = event.payload;
    console.log("11111", filePath)
    setTimeout(()=>{
      info("-----image:" + filePath)
    }, 10*1000)
    info('image 文件路径:{}' + filePath);
  });
})

上述代码看起来比较合理,但是如果后端加载先于前端,就会导致前端拿不到数据,事实经过测试也确实是这样的。

思路二

后端拿到数据以后将文件路径存储起来,当前端就绪以后,主动调用后端方法,获取文件路径,然后进行显示:

rust 复制代码
use tauri::{Manager, State};
use std::sync::Mutex;

#[derive(Default)]
struct StartupImagePath(Mutex<Option<String>>);

#[tauri::command]
fn get_startup_image_path(state: State<StartupImagePath>) -> Option<String> {
    state.0.lock().unwrap().clone()
}

fn main() {
    tauri::Builder::default()
        .manage(StartupImagePath::default()) // ✅ 注册状态
        .setup(|app| {
            let args: Vec<String> = std::env::args().collect();
            for arg in args {
                if arg.ends_with(".jpg") || arg.ends_with(".png") {
                    app.state::<StartupImagePath>()
                        .0
                        .lock()
                        .unwrap()
                        .replace(arg);
                }
            }
            Ok(())
        })
        .invoke_handler(tauri::generate_handler![get_startup_image_path])
        .run(tauri::generate_context!())
        .expect("error while running tauri application");
}
js 复制代码
invoke('get_startup_image_path').then(path => {
  if (path){
    console.log("path=", path)
    filePath.value = path
    info("path" + path);
  }
})

上述代码可以实现我们的需求,但是有一个潜在问题:我们希望右键文件打开app的时候能够触发这套逻辑,但是如果这么写的话,正常双击app图标打开也会调用完整的代码。

总结

本文主要描述了如何为tauri开发的app关联右键菜单。以后关联后如何触发后续软件的行为。 同时介绍了一种比较特殊的情况:当需要将后端数据传递给前端的时候,采用什么方式比较有效。但是仍然存在一定的问题。如果各位有更好的方式、欢迎留言。

相关推荐
Hexene...10 小时前
【前端Vue】如何实现echarts图表根据父元素宽度自适应大小
前端·vue.js·echarts
初遇你时动了情10 小时前
腾讯地图 vue3 使用 封装 地图组件
javascript·vue.js·腾讯地图
华子w90892585911 小时前
基于 SpringBoot+VueJS 的农产品研究报告管理系统设计与实现
vue.js·spring boot·后端
前端小趴菜0513 小时前
React-forwardRef-useImperativeHandle
前端·vue.js·react.js
P7Dreamer13 小时前
Vue 3 + Element Plus 实现可定制的动态表格列配置组件
前端·vue.js
I'm写代码13 小时前
el-tree树形结构笔记
javascript·vue.js·笔记
斯~内克14 小时前
基于Vue.js和PDF-Lib的条形码生成与批量打印方案
前端·vue.js·pdf
sunbyte15 小时前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | ContentPlaceholder(背景占位)
前端·javascript·css·vue.js·tailwindcss
markyankee10115 小时前
Vue 计算属性和侦听器详解
vue.js
盏茶作酒2916 小时前
打造自己的组件库(一)宏函数解析
前端·vue.js