0%

caj2pdf

caj转pdf

某天拿到了一个caj转pdf的工具,是用pyQt写的,好像大小得100MB,就把这个拆解了一下然后用Tauri重新写了一下前端,同时练一练刚学的Tauri。

仓库:Creeeeeeeeeeper/caj2pdf: CAJ file convert to PDF, based on Tauri (github.com)

可以直接下载release版(仅测试过Win11)

PixPin_2025-04-04_19-09-13


下面记录一下在开发过程中遇到的几个问题

1.Tauri使用的js是原生的js,不是nodejs,没法直接获取文件的绝对路径

因为要构建命令行,所以需要获取到文件的绝对路径传到参数上,这里仅需要这个路径即可,也不需要将这个文件同时读取出来,所以就直接用的rust获取这个路径,js只负责调用一下:

1
2
3
4
5
6
7
8
9
10
11
12
use rfd::FileDialog;

#[tauri::command]
pub fn get_files() -> Result<String, String> {
match FileDialog::new().pick_files() {
Some(paths) => {
let paths_str: Vec<String> = paths.iter().map(|path| path.display().to_string()).collect();
Ok(paths_str.join("\n"))
},
None => Err(String::from("No file selected"))
}
}

这样获取的就是文件的绝对路径,每行一个(可选择多个文件)

然后js接收到再转成一个数组进行后续操作即可

1
2
3
function convertMultilineTextToArray(text) {
return text.split('\n');
}

2.因为拿到了一个类似于命令行工具,所以在传参数的时候出了一些小插曲

一开始是这样传的参数:

1
let args_F = format!("/C chcp 65001 >nul && t1.exe convert \"{}\" -m t2.exe", name);

因为文件名参数中可能包含空格,所以就format的时候加了两个引号,但是没有起作用

调试了一下午才发现,/C需要放在chcp的后边,放在t1.exe ...的前面才生效(添加/C处理包含空格的情况)

也就变成了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
use std::process::Command;
use std::os::windows::process::CommandExt;

#[tauri::command]
pub fn spawn_exe(name: &str) -> Result<String, String> {
let output = Command::new("cmd")
.creation_flags(0x08000000)
.arg("chcp 65001 >nul")
.arg("&&")
.arg("/C")
.arg("t1.exe")
.arg("convert")
.arg(name)
.arg("-m")
.arg("t2.exe")
.output()
.expect("failed to execute process");
if output.status.success() {
return Ok(String::from_utf8_lossy(&output.stdout).to_string());
} else {
return Ok(String::from_utf8_lossy(&output.stderr).to_string());
}
}

3.MessageBox出现乱码

Cargo.toml需要添加一个

1
widestring = "0.4"
1
2
3
4
5
6
7
8
9
10
11
use winapi::um::winuser::{MessageBoxW, MB_OK};
use widestring::WideCString;

#[tauri::command]
pub fn converting() {
let title = WideCString::from_str("提示").unwrap();
let message = WideCString::from_str("正在转换,请稍候...").unwrap();
unsafe {
MessageBoxW(null_mut(), message.as_ptr(), title.as_ptr(), MB_OK);
}
}

然后使用MessageBoxW就没问题了