编写插件权限
此练习的目标是更好地理解在编写自己的插件时如何创建插件权限。
最后,您将能够为您的插件创建简单的权限。您将拥有一个示例 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
权限中。将此添加到我们的默认权限集,以允许我们刚刚公开的新命令。
permissions/default.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