0.前半段和后半段
Tauri的安装、启动、打包和很多用例(第一部分)
Tauri的用例(第二部分)
1.安装nvm
访问nvm官网下载nvm用于管理Node.js
nvm list available
显示可下载版本并记录最新LTS版本
2023年2月13日星期一19:00,最新LTS版本为18.14.0
nvm install 18.14.0
安装最新LTS版本
nvm use 18.14.0
使用最新LTS版本
node -v&&npm -v
查看Node.js和npm的当前版本
npm install --global yarn
安装yarn
2.安装Microsoft C++ 生成工具
访问微软官网下载生成工具,勾选"使用 C++ 的桌面开发"之后会自动勾选5个项目
取消勾选以下项目
用于 Windows 的 C++ CMake 工具
测试工具核心功能 - 生成工具
C++ AddressSanitizer
只保留以下两个(SDK版本不用管,Win10或Win11都行,勾什么就留什么,不用自己勾)
MSVC v143 - VS 2022 C++ x64/x86 生成工具
Windows 11 SDK (10.0.22000.0)
3.安装Rust
安装前必须重启电脑
访问Rust官网下载并安装Rust
4.配置镜像
运行where rustc
找到.cargo
文件夹
在.cargo
文件夹下新建无后缀文件,文件名为config,并输入以下内容,保存
[source.crates-io]
registry = "https://github.com/rust-lang/crates.io-index"
replace-with = 'ustc'
[source.ustc]
registry = "git://mirrors.ustc.edu.cn/crates.io-index"
5.安装WebView2
Win11已预装了WebView2(Win10应该也更新了)。
访问微软官网下载并安装常青版独立安装程序的x64版本(网络好的也可以下载引导版本)
6.安装VSCode
下载安装VSCode
安装插件:Tauri插件、rust-analyzer插件
7.修改PowerShell执行策略
PowerShell运行Get-ExecutionPolicy
,如果结果不是RemoteSigned
则按以下操作修改PowerShell的执行策略
PowerShell运行Set-ExecutionPolicy RemoteSigned
后输入A
确认,修改PowerShell的执行策略
PowerShell只需要修改一次执行策略
8.create-tauri-app vanilla
注意:.\tauri-app\src-tauri\tauri.conf.json
中的 withGlobalTauri 设置项,在文档中的默认值是false
,在create-tauri-app(crates渠道/npm渠道)中被设置为true
yarn create tauri-app
快速地创建一个新 Tauri 项目。
Project name?
直接回车跳过
Choose your package manager?
yarn
Choose your UI template?
vanilla
依次输入以下命令
cd tauri-app
yarn
yarn tauri dev
等待大约5分钟,窗口出现。
关闭窗口
8.1.编译结束音效提示
1、向.\tauri-app\src\index.html
,添加一个声音标签,软件启动时有声音提醒
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
<body>
...
<audio controls autoplay>
<source src="/assets/easy-lifestyle-137766.mp3" type="audio/mpeg" />
</audio>
</body>
</html>
2、yarn tauri build
改为yarn tauri build ; echo ^G
(使用快捷键Ctrl+G
输入^G
)(CMD中改为yarn tauri build && echo ^G
)
打包完成后会有系统提示音
9.打包
1、打开.\tauri-app\src-tauri\tauri.conf.json
文件修改identifier
,添加tauri.bundle.windows.wix.language
修改前
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
],
"identifier": "com.tauri.dev",
"longDescription": "",
修改后(identifier改成什么都行,这里就加个not)
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
],
"identifier": "notcom.nottauri.notdev",
""
"longDescription": "",
2、打开.\tauri-app\src-tauri\tauri.conf.json
文件,添加tauri.bundle.windows.wix.language
修改前
"windows": {
"certificateThumbprint": null,
"digestAlgorithm": "sha256",
"timestampUrl": ""
}
修改后
"windows": {
"certificateThumbprint": null,
"wix": { "language": "zh-CN" },
"digestAlgorithm": "sha256",
"timestampUrl": ""
}
3、在项目目录.\tauri-app
运行yarn tauri build
,等待漫长编译时间,得到两个文件
4、免安装exe文件路径:.\tauri-app\src-tauri\target\release\tauri-app.exe
安装包msi文件路径:.\tauri-app\src-tauri\target\release\bundle\msi\tauri-app_0.0.0_x64_zh-CN.msi
9.1.因为wix无法下载打包失败
显示的错误如下
Downloading https://github.com/wixtoolset/wix3/releases/download/wix3112rtm/wix311-binaries.zip
Error failed to bundle project: `TlsError: 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 (os error 10060)`: Tls Error: 由于连接方在一段时间后没有正确答复或连接的主机没有反应,连接尝试失败。 (os error 10060)
解决方法:
保证可连接Github后重试或者打开目录%LocalAppData%
手动创建路径.\AppData\Local\tauri\WixTools
(或者叫%LocalAppData%\tauri\WixTools
)
复制失败时显示的wix下载地址,使用Github镜像站、加速器、hosts文件、Github文件代下载等方式下载wix压缩包
将下载完的压缩包解压至刚创建完毕的路径里,类似这样%LocalAppData%\tauri\WixTools\dark.exe
,然后再次打包即可。WixTools只会下载一次
10.main.js
.\tauri-app\src\main.js
// 访问已打包好的全局 API 函数
const { invoke } = window.__TAURI__.tauri;
// 输入框元素
let greetInputEl;
// 欢迎信息元素
let greetMsgEl;
async function greet() {
// 更多 Tauri commands 移步 Tauri指南,https://tauri.app/zh-cn/v1/guides/features/command/
greetMsgEl.textContent = await invoke("greet", {
name: greetInputEl.value,
});
}
// 当初始HTML文档已完全加载和解析时,向按钮元素添加监听事件。
window.addEventListener("DOMContentLoaded", () => {
greetInputEl = document.querySelector("#greet-input");
greetMsgEl = document.querySelector("#greet-msg");
document
.querySelector("#greet-button")
.addEventListener("click", () => greet());
});
11.main.rs
.\tauri-app\src-tauri\src\main.rs
// https://www.rustwiki.org.cn/zh-CN/reference/conditional-compilation.html?highlight=cfg_attr#cfg_attr%E5%B1%9E%E6%80%A7
// 构建完毕的应用在 Windows 上运行时一般会出现控制台窗口。这段代码表示不显示这个控制台窗口。
// 注释这段代码会显示控制台窗口。
// 将windows_subsystem = "windows"改为windows_subsystem = "console",也会显示控制台窗口。
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
// 更多 Tauri commands 移步 Tauri指南,https://tauri.app/zh-cn/v1/guides/features/command/
// 拥有 #[tauri::command] 宏的函数可以被 JavaScript 调用。
#[tauri::command]
fn greet(name: &str) -> String {
format!("你好, {}!这是来自Rust的问候!", name)
}
// main 函数是所有 Rust 程序的入口点。
fn main() {
// .invoke_handler() 函数配合 generate_handler![] 宏注册指令。
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![greet])
.run(tauri::generate_context!())
.expect("运行 tauri 应用程序时出错");
}
12.解决Tauri文档页面全是黑色字分不清主次的问题
document.querySelectorAll("h2").forEach((i)=>{i.style = "background-color: tan;"});
document.querySelectorAll("h3").forEach((i)=>{i.style = "background-color: #d2b48c99;"});
13.以编程方式打开开发工具
修改main.rs
的main
函数,运行yarn tauri dev
,Devtools窗口 和 Tauri窗口 将同时显示
fn main() {
tauri::Builder::default()
.setup(|app| {
use tauri::Manager;
#[cfg(debug_assertions)] //仅在调试时自动打开开发者工具
{
let main_window = app.get_window("main").unwrap();
main_window.open_devtools();
}
Ok(())
})
.invoke_handler(tauri::generate_handler![greet])
.run(tauri::generate_context!())
.expect("错啦!");
}
14.获取所有窗口,获取自身窗口
只要启用withGlobalTauri
就可以获取窗口
const tauriWindow = window.__TAURI__.window;
console.log(tauriWindow.getAll());
console.log(tauriWindow.getCurrent());
15.tauri响应javascript的alert
tcfg-alert
main.js
的greet
函数:async function greet() { alert(greetInputEl.value); }
tauri.conf.json
:{ "tauri": { "allowlist": { "dialog": { "message": true } } } }
yarn tauri dev
,点击Greet
按钮,出现弹窗提示
16.rust读取文件
按步骤8新建一个名为tauri-rust-readfile
的项目
1、在.\tauri-rust-readfile\src-tauri
目录运行cargo add dirs
2、准备一个TextEditor.txt
的文件放置在桌面上,随便写点内容
1.VSCode
2.SublimeText
3.Kate
3、将.\tauri-rust-readfile\src\main.js
的greet
函数改为read_texteditor_file
函数,并修改按钮元素的监听事件
const { invoke } = window.__TAURI__.tauri;
let greetInputEl;
let greetMsgEl;
async function read_texteditor_file() {
greetMsgEl.textContent = await invoke("read_texteditor_file");
}
window.addEventListener("DOMContentLoaded", () => {
greetInputEl = document.querySelector("#greet-input");
greetMsgEl = document.querySelector("#greet-msg");
document
.querySelector("#greet-button")
.addEventListener("click", () => read_texteditor_file());
});
4、同样的,将.\tauri-rust-readfile\src-tauri\src\main.rs
的greet
函数改为read_texteditor_file
函数
注意不要落下.invoke_handler(tauri::generate_handler![read_texteditor_file])
中的read_texteditor_file
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
#[tauri::command]
fn read_texteditor_file() -> String {
let mut textfile = dirs::desktop_dir().expect("找不到桌面路径");
textfile.push("folderfortauri");
textfile.push("TextEditor.txt");
let data = std::fs::read_to_string(textfile);
match data {
Ok(text) => text,
Err(_) => "文件打开失败".to_string(),
}
}
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![read_texteditor_file])
.run(tauri::generate_context!())
.expect("运行 tauri 应用程序时出错");
}
5、在项目目录.\tauri-rust-readfile
运行yarn tauri dev
等待编译完成,窗口出现,点击Greet
按钮,成功读取文件内容
17.javascript读取文件
按步骤8新建一个名为tauri-js-readfile
的项目
1、在.\tauri-js-readfile\src-tauri\tauri.conf.json
中配置fs
的读取文件范围,启用exists
和readfile
{
...
"tauri": {
"allowlist": {
"all": false,
"shell": {
"all": false,
"open": true
},
"fs": {
"exists": true,
"readFile": true,
"scope": ["$DESKTOP/folderfortauri/*"]
}
},
...
...
}
2、修改.\tauri-js-readfile\src\main.js
const { invoke } = window.__TAURI__.tauri;
const { readTextFile, exists, BaseDirectory } = window.__TAURI__.fs;
let greetInputEl;
let greetMsgEl;
async function read_texteditor_file() {
let textfile = "folderfortauri\\TextEditor.txt";
if (await exists(textfile, { dir: BaseDirectory.Desktop })) {
greetMsgEl.textContent = await readTextFile(textfile, {
dir: BaseDirectory.Desktop,
});
} else {
console.error(textfile + ",该文件不存在!");
greetMsgEl.textContent = textfile + ",该文件不存在!";
}
}
window.addEventListener("DOMContentLoaded", () => {
greetInputEl = document.querySelector("#greet-input");
greetMsgEl = document.querySelector("#greet-msg");
document
.querySelector("#greet-button")
.addEventListener("click", () => read_texteditor_file());
});
3、在项目目录.\tauri-rust-readfile
运行yarn tauri dev
,点击Greet
按钮,成功读取文件内容
allowlistconfig - tauri文档,第二项就是fs
(window.__TAURI__.fs
)
fs安全设置 - tauri文档
BaseDirectory - tauri文档
fsallowlistscope - tauri文档
CSIDL - 微软
KNOWNFOLDERID - 微软
https://tauri.app/zh-cn/v1/api/js/path
Config %APPDATA%
AppConfig %APPDATA%\com.tauri.dev
Data %APPDATA%
AppData %APPDATA%\com.tauri.dev
Log %APPDATA%\com.tauri.dev\logs(即将废弃,会被AppLog取代)
AppLog %APPDATA%\com.tauri.dev\logs
LocalData %LOCALAPPDATA%
AppLocalData %LOCALAPPDATA%\com.tauri.dev
Cache %LOCALAPPDATA%
AppCache %LOCALAPPDATA%\com.tauri.dev
Home %LocalAppdata%\com.tauri.dev
Audio %USERPROFILE%\Music
Desktop %USERPROFILE%\Desktop
Document %USERPROFILE%\Documents
Download %USERPROFILE%\Downloads
Picture %USERPROFILE%\Pictures
Video %USERPROFILE%\Videos
Public %PUBLIC%
Resource \\?\D:\tauri-js-readfile\src-tauri\target\debug(不知道\\?\是什么意思)
App %APPDATA%\com.tauri.dev(即将废弃,会被AppConfig和appDataDir取代)
Temp 通常是%USERPROFILE%\AppData\Local\Temp
Template %APPDATA%\Microsoft\Windows\Templates;Linux: xdg-user-dirs' XDG_TEMPLATES_DIR;不支持macOS
Font 不支持Windows;Linux: $XDG_DATA_HOME/fonts or $HOME/.local/share/fonts;macOS: $HOME/Library/Fonts
Runtime 仅支持Linux: $XDG_RUNTIME_DIR
Executable 仅支持Linux: $XDG_BIN_HOME/../bin or $XDG_DATA_HOME/../bin or $HOME/.local/bin
scope
应该设置为列表,包含一个或多个路径,类似下面这样
"scope": ["$DESKTOP/folderfortauri/*"]
// 或者
"scope": ["$TEMP/tauri_temp/*", "$APPDATA/databases/*"]
18.javaScript动态创建新窗口
按步骤8新建一个名为tauri-js-openwindow2
的项目
编辑.\tauri-js-openwindow2\src-tauri\tauri.conf.json
,添加tauri.allowlist.window.create
,设置为true
{
...
"tauri": {
"allowlist": {
"all": false,
"shell": {
"all": false,
"open": true
},
"window": {
"create": true
}
},
...
}
}
编辑.\tauri-js-openwindow2\src\main.js
中的greet
函数
async function greet() {
const { WebviewWindow } = window.__TAURI__.window;
const webview = new WebviewWindow("w2", {
url: "https://tauri.app/zh-cn/v1/guides/features/multiwindow#%E5%9C%A8-javascript-%E4%B8%AD%E5%88%9B%E5%BB%BA%E7%AA%97%E5%8F%A3",
});
// 由于 webview 窗口是异步创建的,
// 窗口创建成功会调用 `tauri://created`
// 窗口创建失败会调用 `tauri://error`
webview.once("tauri://created", function () {
console.log("创建窗口成功");
});
webview.once("tauri://error", function (e) {
console.error("创建窗口失败: " + e.payload);
console.log(e);
});
}
运行yarn tauri dev
,点击Greet
按钮
tauri.conf.json 中的 window 配置
WindowAllowlistConfig
19.静态多窗口,javaScript控制窗口的显示和隐藏
按步骤8创建tauri-config-staticwindow
项目
1、修改.\tauri-config-staticwindow\src-tauri\tauri.conf.json
添加tauri.allowlist.window
的show
、hide
,添加两个label
,一个visible
{
...
"tauri": {
"allowlist": {
"all": false,
"shell": {
"all": false,
"open": true
},
"window":{
"show": true,
"hide": true
}
},
...
"windows": [
{
"label": "w1",
"fullscreen": false,
"height": 600,
"resizable": true,
"title": "tauri-config-staticwindow",
"width": 800
},
{
"label": "w2",
"visible": false
}
]
}
}
2、修改.\tauri-config-staticwindow\src\main.js
的greet
函数
let w2_isshow = false;
async function greet() {
const { WebviewWindow } = window.__TAURI__.window;
const w2 = WebviewWindow.getByLabel("w2");
w2_isshow ? w2.hide() : w2.show();
w2_isshow = !w2_isshow;
}
3、运行yarn tauri dev
,多次点击"tauri-config-staticwindow"窗口的Greet
按钮,成功显示和隐藏新窗口
20.rust动态创建新窗口
按步骤8创建tauri-rust-openwindow2
项目
1、将.\tauri-rust-openwindow2\src-tauri\src\main.rs
的greet
函数改为open_docs
函数
注意不要落下tauri::generate_handler![open_docs]
中的open_docs
#![cfg_attr(
all(not(debug_assertions), target_os = "windows"),
windows_subsystem = "windows"
)]
// javaScript 使用 open_docs 函数时并不需要 handle 参数
// 命令可以访问调用消息的```Window```实例和```AppHandle```实例,tauri不会让js感知到这两个参数的存在
#[tauri::command]
async fn open_docs(handle: tauri::AppHandle) {
let doc_url = "https://tauri.app/zh-cn/v1/guides/features/multiwindow";
let _docs_window = tauri::WindowBuilder::new(
&handle,
"doc",
tauri::WindowUrl::External(doc_url.parse().unwrap()),
)
.build()
.unwrap();
}
fn main() {
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![open_docs])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
2、编辑.\tauri-rust-openwindow2\src\main.js
中的greet
函数
命令可以访问调用消息的Window
实例和AppHandle
实例,tauri不会让js感知到这两个参数的存在
async function greet() {
greetMsgEl.textContent = await invoke("open_docs", {
/*!!没有参数!!*/
});
document.querySelector("#greet-button").disabled = true;
}
3、还可以添加一些css,编辑.\tauri-rust-openwindow2\src\style.css
,在button:hover
的下面添加以下内容
button:hover {
border-color: #396cd8;
}
button:disabled {
border: 1px solid #999999;
background-color: #cccccc;
color: #666666;
text-decoration: line-through;
}
button:disabled:hover {
cursor: not-allowed;
}
4、运行yarn tauri dev
,点击Greet
按钮,成功显示新窗口
98.yarn tauri dev 报错 failed to download
error: failed to download from `https://crates-io.proxy.ustclug.org/api/v1/crates/http/0.2.9/download`
镜像抽风,换其他镜像,字节镜像,中国科学技术大学,上海交通大学,清华大学
99.其他
1、F12
、Ctrl+Shift+I
、右键-检查
可以打开 DevTools,打包后默认禁用。要想启用 DevTools 可以参考:①手动启用开发工具功能,②yarn tauri build --debug
,③Eruda
2、结束 Tauri 程序要确认命令行已结束(或者使用--no-watch
参数、Ctrl+C
强制结束命令),之后再修改代码,否则Tauri会优先编译,窗口跳出来吓你。文件不需要编译的(例如html
),会立即生效。
3、Tauri 不能使用 Node.js,除非使用 sidecar 功能
4、项目名称最好遵守蛇形命名法,以免编译完报warning
5、Tauri 中的|app|
属于 Rust 的闭包语法
100.文档
使用 Rust 迈出第一步 - 微软
通过例子学 Rust
Rust练习场,在线运行
Rust 参考手册 中文版、Rust语言学习笔记、Rust学习笔记、RustPrimer、Rust在线教程
Tauri指南、Tauri文档、Tauri事件、Tauri特性、Tauri API
GitHub Discussions - Tauri 系列
Node.js在线运行、HTML/CSS/JS在线运行