Skip to content
Tauri 中文网

单个实例

GitHub crates.io
API Reference

使用单实例插件确保你的 tauri 应用一次只运行一个实例。

¥Ensure that a single instance of your tauri app is running at a time using the Single Instance Plugin.

支持的平台

¥Supported Platforms

This plugin requires a Rust version of at least 1.77.2

Platform Level Notes
windows
linux
macos
android
ios

设置

¥Setup

安装单实例插件以开始使用。

¥Install the Single Instance plugin to get started.

使用项目的包管理器添加依赖:

¥Use your project’s package manager to add the dependency:

npm run tauri add single-instance

:::info 信息

单实例插件必须是第一个注册的插件才能正常工作。这确保它在其他插件干扰之前运行。

¥The Single Instance plugin must be the first one to be registered to work well. This assures that it runs before other plugins can interfere.

:::

使用

¥Usage

插件已安装并初始化,应该可以立即正常运行。尽管如此,我们也可以使用 init() 方法增强其功能。

¥The plugin is already installed and initialized, and it should be functioning correctly right away. Nevertheless, we can also enhance its functionality with the init() method.

插件 init() 方法采用闭包,当启动新的应用实例但由插件关闭时调用该闭包。闭包有三个参数:

¥The plugin init() method takes a closure that is invoked when a new app instance was started, but closed by the plugin. The closure has three arguments:

  1. app:应用的 AppHandle

    ¥app: The AppHandle of the application.

  2. args:用户传递的用于启动此新实例的参数列表。

    ¥args: The list of arguments, that was passed by the user to initiate this new instance.

  3. cwd:当前工作目录表示启动新应用实例的目录。

    ¥cwd: The Current Working Directory denotes the directory from which the new application instance was launched.

因此,闭包应如下所示

¥So, the closure should look like below

.plugin(tauri_plugin_single_instance::init(|app, args, cwd| {
// Write your code here...
}))

专注于新实例

¥Focusing on New Instance

默认情况下,当你在应用已运行时启动新实例时,不会采取任何行动。要在用户尝试打开新实例时聚焦正在运行的实例的窗口,请按如下方式更改回调闭包:

¥By default, when you initiate a new instance while the application is already running, no action is taken. To focus the window of the running instance when user tries to open a new instance, alter the callback closure as follows:

src-tauri/src/lib.rs
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");
}

在 Snap 和 Flatpak 中的使用

¥Usage in Snap and Flatpak

在 Linux 上,单实例插件使用 DBus 来确保只有一个实例在运行。它通过在第一个实例开始运行时将服务发布到 DBus 来实现此目的。然后,后续实例将尝试发布相同的服务,如果该服务已发布,它们将向该服务发送请求以通知第一个实例,并立即退出。

¥On Linux the Single Instance plugin uses DBus to ensure that there will be only one instance running. It does so by publishing a service to DBus when the first instance starts running. Then, the following instances will try to publish the same service and, if it is already published, they will send a request to the service to notify the first instance, and exit right away.

虽然当你的应用以 deb、rpm 包或 AppImage 的形式打包时,这种方法运行良好,但默认情况下,它无法按预期用于 snap 或 flatpak 包,因为这些包运行在受限的沙盒环境中,如果未在打包清单中明确声明,则大多数与 DBus 服务的通信都会被阻止。

¥Despite this working pretty well when your app is bundled as a deb or rpm package or an AppImage, it won’t work as intended for snap or flatpak packages by default because these packages run in a constrained sandboxed environment, where most of the communication to DBus services will be blocked if not explicitly declared on the packaging manifest.

以下指南展示了如何声明所需的权限以启用 snap 和 flatpak 软件包的单实例:

¥Here’s a guide that shows how to declare the needed permissions to enable the Single Instance for snap and flatpak packages:

获取你的应用 ID

¥Getting your app ID

单实例插件将发布一个名为 org.{id}.SingleInstance 的服务。

¥The Single Instance plugin will publish a service named org.{id}.SingleInstance.

{id} 将是你的 tauri.conf.json 文件中的 identifier,但其中的点 (.) 和破折号 (-) 被下划线 (_) 取代。

¥{id} will be the identifier from your tauri.conf.json file, but with with dots (.) and dashes (-) replaced by underline (_).

例如,如果你的标识符是 net.mydomain.MyApp

¥For example, if your identifier is net.mydomain.MyApp:

  • net_mydomain_MyApp 是你的应用的 {id}

    ¥net_mydomain_MyApp will be your app {id}

  • org.net_mydomain_MyApp.SingleInstance 是你应用的单实例服务名称

    ¥org.net_mydomain_MyApp.SingleInstance will be your app SingleInstance service name

你需要该服务名称来授权你的应用在 snap 和 flatpak 清单中使用 DBus 服务,如下所示。

¥You will need the service name to authorize your app to use the DBus service on snap and flatpak manifests, as seen below.

Snap

在你的 snapcraft.yml 文件中,为单实例服务声明一个插头和一个插槽,并在你的应用声明中同时使用它们:

¥In your snapcraft.yml file, declare a plug and a slot for the single instance service, and use both on your app declaration:

snapcraft.yml
# ...
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 服务发送和接收请求。

¥This will allow your app to send and receive requests from/to the DBus service as expected by the Single Instance plugin.

Flatpak

在你的 Flatpak 清单文件(your.app.id.yml 或 your.app.id.json)中,使用服务名称声明 --talk-name--own-name 完成参数:

¥In your flatpak manifest file (your.app.id.yml or your.app.id.json), declare a --talk-name and a --own-name finish args with the service name:

net.mydomain.MyApp.yml
# ...
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 服务发送和接收请求。

¥This will allow your app to send and receive requests from/to the DBus service as expected by the Single Instance plugin.


Tauri v2.6 中文网 - 粤ICP备13048890号
Nodejs.cn 旗下网站