单实例
使用单实例插件确保您的 Tauri 应用只运行一个实例。
此插件需要 Rust 版本至少为 **1.77.2**
平台 | 级别 | 备注 |
---|---|---|
Windows | ||
Linux | ||
macOS | ||
Android | | |
iOS | |
安装 Single Instance 插件即可开始使用。
使用你的项目包管理器添加依赖项
npm run tauri add single-instance
yarn run tauri add single-instance
pnpm tauri add single-instance
deno task tauri add single-instance
bun tauri add single-instance
cargo tauri add single-instance
-
在
src-tauri
文件夹中运行以下命令,将插件添加到项目的Cargo.toml
依赖项中cargo add tauri-plugin-single-instance --target 'cfg(any(target_os = "macos", windows, target_os = "linux"))' -
修改
lib.rs
以初始化插件lib.rs #[cfg_attr(mobile, tauri::mobile_entry_point)]pub fn run() {tauri::Builder::default().setup(|app| {#[cfg(desktop)]app.handle().plugin(tauri_plugin_single_instance::init(|app, args, cwd| {}));Ok(())}).run(tauri::generate_context!()).expect("error while running tauri application");}
单实例插件必须是第一个被注册的插件才能正常工作。这确保它在其他插件干扰之前运行。
插件已经安装并初始化,应该能立即正常工作。尽管如此,我们还可以使用 init()
方法增强其功能。
插件的 init()
方法接受一个闭包,当一个新的应用程序实例启动但被插件关闭时,该闭包会被调用。该闭包有三个参数:
app
: 应用程序的 AppHandle。args
: 用户为启动此新实例而传递的参数列表。cwd
: 当前工作目录表示启动新应用程序实例的目录。
因此,闭包应该如下所示:
.plugin(tauri_plugin_single_instance::init(|app, args, cwd| { // Write your code here...}))
默认情况下,当您在应用程序已经运行时启动新实例时,不执行任何操作。要将焦点聚焦到正在运行的实例的窗口,当用户尝试打开新实例时,请按如下方式更改回调闭包:
use tauri::{AppHandle, Manager};
pub fn run() { let mut builder = tauri::Builder::default(); #[cfg(desktop)] { builder = builder.plugin(tauri_plugin_single_instance::init(|app, args, cwd| { let _ = app.get_webview_window("main") .expect("no main window") .set_focus(); })); }
builder .run(tauri::generate_context!()) .expect("error while running tauri application");}
在 Linux 上,单实例插件使用 DBus 来确保只有一个实例在运行。它通过在第一个实例开始运行时向 DBus 发布服务来实现。然后,后续实例将尝试发布相同的服务,如果该服务已发布,它们将向该服务发送请求以通知第一个实例,并立即退出。
尽管这在您的应用程序捆绑为 deb 或 rpm 包或 AppImage 时运行良好,但默认情况下,它不适用于 snap 或 flatpak 包,因为这些包在受限的沙盒环境中运行,如果未在打包清单中明确声明,大多数对 DBus 服务的通信将被阻止。
以下指南显示了如何声明所需的权限,以启用 snap 和 flatpak 包的单实例功能:
单实例插件将发布一个名为 org.{id}.SingleInstance
的服务。
{id}
将是您的 tauri.conf.json
文件中的 identifier
,但其中的点 (.
) 和破折号 (-
) 将被下划线 (_
) 替换。
例如,如果您的标识符是 net.mydomain.MyApp
net_mydomain_MyApp
将是您的应用{id}
org.net_mydomain_MyApp.SingleInstance
将是您的应用单实例服务名称
您将需要服务名称来授权您的应用程序在 snap 和 flatpak 清单中使用 DBus 服务,如下所示。
在您的 snapcraft.yml 文件中,为单实例服务声明一个 plug 和一个 slot,并在您的应用程序声明中同时使用它们。
# ...slots: single-instance: interface: dbus bus: session name: org.net_mydomain_MyApp.SingleInstance # Remember to change net_mydomain_MyApp to your app ID
plugs: single-instance-plug: interface: dbus bus: session name: org.net_mydomain_MyApp.SingleInstance # Remember to change net_mydomain_MyApp to your app ID
# .....apps: my-app: # ... plugs: # .... - single-instance-plug slots: # ... - single-instance
# ....
这将允许您的应用程序按单实例插件的预期发送和接收来自 DBus 服务的请求。
在您的 flatpak 清单文件(your.app.id.yml 或 your.app.id.json)中,声明一个 --talk-name
和一个 --own-name
结束参数,并附带服务名称。
# ...finish-args: - --socket=wayland - --socket=fallback-x11 - --device=dri - --share=ipc # .... - --talk-name=org.net_mydomain_MyApp.SingleInstance # Remember to change net_mydomain_MyApp to your app ID - --own-name=org.net_mydomain_MyApp.SingleInstance # Remember to change net_mydomain_MyApp to your app ID# ...
这将允许您的应用程序按单实例插件的预期发送和接收来自 DBus 服务的请求。
© 2025 Tauri 贡献者。CC-BY / MIT