前言
尝试使用tauri2+Django+React的项目-CSDN博客https://blog.csdn.net/qq_63401240/article/details/146403103在前面笔者不知道怎么做,搞了半天
笔者看到官网,原来可以使用二进制文件,好好好
嵌入外部二进制文件 | Taurihttps://v2.tauri.app/zh-cn/develop/sidecar/
准备
根据官网,进入如下配置
1、在src-tauri目录下新建bin或者binaries
2、将manage.exe(Django打包文件)放入bin目录下,并且按照操作系统改名,笔者改的名
manage-x86_64-pc-windows-msvc。
3、在配置文件tauri.config.json中,在bundle添加值binaries/manage
"bundle": {
"active": true,
"targets": "all",
"externalBin": [
"binaries/manage"
],
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
]
}
4、配置许可
{
....
"shell:allow-execute",
"shell:allow-kill",
}
正文
1、运行时,打开exe
2、关闭时,断开exe
思考
如何在运行项目时,打开exe?
这需要用到tauri的一个结构体Builder,,其中有个方法setup,项目运行时,就会运行其中的代码
Builder in tauri - Rusthttps://docs.rs/tauri/2.4.0/tauri/struct.Builder.html#method.setup
如何关闭项目时,关闭exe
使用build中的窗口事件on_window_event。
Builder in tauri - Rusthttps://docs.rs/tauri/2.4.0/tauri/struct.Builder.html#method.on_window_event
关键代码如下
use std::sync::{Arc, Mutex};
.........
.........
.setup(|app| {
let sidecar_child = Arc::new(Mutex::new(None)); // 用于存储 CommandChild 对象
app.manage(sidecar_child.clone()); // 将 sidecar_child 存储在全局状态中
let app_handle = app.handle().clone();
let sidecar_command = app_handle.shell()
.sidecar("manage")
.unwrap()
.args(["runserver", "--noreload"]);// 启动命令
// 检查是否已经启动了子进程
if sidecar_child.lock().unwrap().is_none() {
match sidecar_command.spawn() {// 启动exe
Ok((mut rx, mut child)) => {
*sidecar_child.lock().unwrap() = Some(child); // 存储子进程
Ok(())
}
Err(e) => {
eprintln!("Failed to spawn sidecar: {}", e);
Err(Box::new(e))
}
}
} else {
Ok(())
}
})
use tauri::WindowEvent;
.....
....
.on_window_event(|window, event| {
if let WindowEvent::CloseRequested { api, .. } = event {
// 获取 Sidecar 进程句柄
let sidecar_child = window.state::<Arc<Mutex<Option<CommandChild>>>>();
if let Some(mut child) = sidecar_child.lock().unwrap().take() {
let _ = child.kill(); // 关闭进程
println!("Sidecar process stopped on window close.");
}
}
})
打包后,打开任务管理器
运行的发现——第一点
打开debug文件,
可以发现其中有manage.exe,如果把它删除,运行会报错。
看来上篇文章中,把manage.exe文件放到debug中,没有问题。
运行的发现——第二点
打开任务管理器,有一个进程,但是为什么会有两个,这两个都是进程,都有PID
这其实笔者感到疑惑
关闭运行
为什么只关掉了一个进程
对于这个问题,笔者打开了bin目录下exe,在powershell中单独打开manage.exe文件
./manage-x86_64-pc-windows-msvc.exe runserver --noreload
查看进程
居然会有两个?,原来本就有两个,以前还没发现
如果关闭powershell
发现两个都关闭了。?????????
难道是manage.exe的问题,打包有问题吗?
笔者打开没有打包之前的后端,运行Django
python manage.py runserver
在任务管理器中,原来有4个python
关闭之后,都关闭了。笔者问了问deepseek
当你运行
python manage.py runserver
时,任务管理器显示有多个 Python 进程是正常现象。这是因为 Django 的开发服务器(runserver
)会启动多个线程或子进程来处理请求和后台任务。
当使用
-F
参数(打包为单个 EXE 文件)时,PyInstaller 会将程序解压缩到一个临时目录并运行。第二个进程是实际的程序,而第一个进程是用于在程序退出或崩溃后清理临时目录的守护进程
原来如此。manage.exe会打开两个进程,而kill方法只关闭了一个进程。
笔者搜了搜,原来是打包的原因,哈哈哈哈哈
python打包的exe运行后有两个进程_mob649e81540090的技术博客_51CTO博客https://blog.51cto.com/u_16175432/8031448Two process instance when i run "exe" which is generated by pyinstaller? · Issue #2483 · pyinstaller/pyinstaller
https://github.com/pyinstaller/pyinstaller/issues/2483
解决这个问题
1、不打包成单个文件
打包成多个文件
pyinstaller manage.exe
结果如下
准备
(1)将_internal放到src-tauri目录下
(2)manage.exe放到bin目录下,并改名
(3)修改配置文件tauri.config.json的bundle
"bundle": {
"active": true,
"targets": "all",
"externalBin": [
"binaries/manage"
],
"resources":[
"_internal"
],
"icon": [
"icons/32x32.png",
"icons/128x128.png",
"icons/128x128@2x.png",
"icons/icon.icns",
"icons/icon.ico"
]
}
运行。
成功,完美,哈哈哈哈哈
2、继续使用单个文件
笔者多次尝试,发现对于打包成单个文件manage.exe的运行过程
首先,没有出现Django的文字的时候,只有一个进程
然后,当下面出现文字,就变成两个
当终结先出现的manage.exe,剩下一个运行,
访问127.0.0.1:8000,是成功的
当终结后出现的manage.exe,全部都关闭
因此,笔者有这个想法,如果在Tauri想办法关闭后面出现的线程,就可以完全关闭。
理论上,笔者觉得没有问题。
为什么不全部关了,哈哈哈哈哈
打包
Tauri打包
运行打包命令
pnpm run tauri:build
安装后,目录如下
可以运行。ok
终于完成了。