编写插件权限
本练习的目标是更好地理解在编写自己的插件时如何创建插件权限。
最后,您将能够为您的插件创建简单的权限。您将拥有一个示例 Tauri 插件,其中权限部分是自动生成和手动制作的。
-
在我们的例子中,我们将使 Tauri 的
cli
启动一个 Tauri 插件源代码结构。请确保您已安装所有 先决条件,并通过运行cargo tauri info
验证您拥有正确版本的 Tauri CLI。输出应指示
tauri-cli
版本是2.x
。我们将在此分步说明中使用pnpm
,但您可以选择其他包管理器,并相应地替换命令。一旦安装了最新版本,您就可以创建插件并使用 Tauri CLI 来完成。
终端窗口 mkdir -p tauri-learningcd tauri-learningcargo tauri plugin new testcd tauri-plugin-testpnpm installpnpm buildcargo build -
为了展示一个实际而简单的情况,让我们假设我们的命令将用户输入写入我们临时文件夹中的一个文件,并向文件添加一些自定义头部。
让我们将我们的命令命名为
write_custom_file
,在src/commands.rs
中实现它,并将其添加到插件构建器中,以便暴露给前端。Tauri 的核心工具将自动为该命令生成
allow
和deny
权限,因此我们不需要关心这个问题。命令实现
src/commands.rs use tauri::{AppHandle, command, Runtime};use crate::models::*;use crate::Result;use crate::TestExt;#[command]pub(crate) async fn ping<R: Runtime>(app: AppHandle<R>,payload: PingRequest,) -> Result<PingResponse> {app.test1().ping(payload)}#[command]pub(crate) async fn write_custom_file<R: Runtime>(user_input: String,app: AppHandle<R>,) -> Result<String> {std::fs::write(app.path().temp_dir().unwrap(), user_input)?;Ok("success".to_string())}自动生成内置权限以用于您的新命令
src/build.rs const COMMANDS: &[&str] = &["ping", "write_custom_file"];这些内置权限将由 Tauri 构建系统自动生成,并在
permissions/autogenerated/commands
文件夹中可见。默认情况下,将创建一个enable-<command>
和deny-<command>
权限。 -
上一步是编写实际的命令实现。接下来,我们希望将其暴露给前端,以便它可以被使用。
配置 Tauri 构建器生成调用处理程序,以将前端 IPC 请求传递到新实现的命令
src/lib.rs pub fn init<R: Runtime>() -> TauriPlugin<R> {Builder::new("test").invoke_handler(tauri::generate_handler![commands::ping,commands::write_custom_file,]).setup(|app, api| {#[cfg(mobile)]let test = mobile::init(app, api)?;#[cfg(desktop)]let test = desktop::init(app, api)?;app.manage(test);// manage state so it is accessible by the commandsapp.manage(MyState::default());Ok(())}).build()}在前端模块中暴露新命令。
此步骤对于示例应用程序成功导入前端模块至关重要。这是为了方便,不会产生安全影响,因为命令处理程序已经生成,并且可以从前端手动调用命令。
guest-js/index.ts import { invoke } from '@tauri-apps/api/core'export async function ping(value: string): Promise<string | null> {return await invoke<{value?: string}>('plugin:test|ping', {payload: {value,},}).then((r) => (r.value ? r.value : null));}export async function writeCustomFile(user_input: string): Promise<string> {return await invoke('plugin:test|write_custom_file',{userInput: user_input});}确保您的包已构建
pnpm build -
由于我们的插件应该默认暴露
write_custom_file
命令,我们应该将其添加到我们的default.toml
权限中。将其添加到我们的默认权限集中,允许我们刚刚曝光的新命令。
权限/默认.toml "$schema" = "schemas/schema.json"[default]description = "Default permissions for the plugin"permissions = ["allow-ping", "allow-write-custom-file"] -
创建的插件目录结构包含一个
examples/tauri-app
文件夹,其中包含了可以立即使用的Tauri应用程序,用于测试插件。由于我们添加了新的命令,因此需要稍微修改前端以调用我们的新命令。
src/App.svelte <script>import Greet from './lib/Greet.svelte'import { ping, writeCustomFile } from 'tauri-plugin-test-api'let response = ''function updateResponse(returnValue) {response += `[${new Date().toLocaleTimeString()}]` + (typeof returnValue === 'string' ? returnValue : JSON.stringify(returnValue)) + '<br>'}function _ping() {ping("Pong!").then(updateResponse).catch(updateResponse)}function _writeCustomFile() {writeCustomFile("HELLO FROM TAURI PLUGIN").then(updateResponse).catch(updateResponse)}</script><main class="container"><h1>Welcome to Tauri!</h1><div class="row"><a href="https://vite.vuejs.ac.cn" target="_blank"><img src="/vite.svg" class="logo vite" alt="Vite Logo" /></a><a href="https://tauri.org.cn" target="_blank"><img src="/tauri.svg" class="logo tauri" alt="Tauri Logo" /></a><a href="https://svelte.net.cn" target="_blank"><img src="/svelte.svg" class="logo svelte" alt="Svelte Logo" /></a></div><p>Click on the Tauri, Vite, and Svelte logos to learn more.</p><div class="row"><Greet /></div><div><button on:click="{_ping}">Ping</button><div>{@html response}</div></div><div><button on:click="{_writeCustomFile}">Write</button><div>{@html response}</div></div></main><style>.logo.vite:hover {filter: drop-shadow(0 0 2em #747bff);}.logo.svelte:hover {filter: drop-shadow(0 0 2em #ff3e00);}</style>运行此程序并点击“写入”按钮,你应该会看到这个界面
success你应该在你的临时文件夹中找到一个
test.txt
文件,它包含了我们新实现的插件命令的消息。🥳
© 2025 Tauri 贡献者。CC-BY / MIT