feat(core): Added core startup and debugging features
- Introduced the tauri-plugin-os, tauri-plugin-shell, and tauri-plugin-process plugins - Added the coreStart function to execute shell commands to start the core - Added the coreLog page and MainConsole component for debugging output - Introduced vue-web-terminal to implement a terminal interface - Removed the old Exe and Group modules and related code
This commit is contained in:
@@ -1,3 +0,0 @@
|
||||
enum Core{
|
||||
XRAY(String),
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::path::PathBuf;
|
||||
use std::process::{Child, Command, Stdio};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
|
||||
pub struct Exe {
|
||||
path: PathBuf,
|
||||
args: Vec<String>,
|
||||
child: Arc<Mutex<Option<Child>>>,
|
||||
pub pid: Arc<Mutex<Option<u32>>>,
|
||||
}
|
||||
|
||||
impl Exe {
|
||||
pub fn new<P: Into<PathBuf>, S: Into<String>>(path: P, args: Vec<S>) -> Self {
|
||||
Self {
|
||||
path: path.into(),
|
||||
args: args.into_iter().map(|s| s.into()).collect(),
|
||||
child: Arc::new(Mutex::new(None)),
|
||||
pid: Arc::new(Mutex::new(None)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn start<F, E, X>(
|
||||
&mut self,
|
||||
mut on_stdout: F,
|
||||
mut on_stderr: E,
|
||||
mut on_exit: X,
|
||||
) -> std::io::Result<()>
|
||||
where
|
||||
F: FnMut(String) + Send + 'static,
|
||||
E: FnMut(String) + Send + 'static,
|
||||
X: FnMut(i32) + Send + 'static,
|
||||
{
|
||||
let mut cmd = Command::new(&self.path);
|
||||
cmd.args(&self.args)
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped());
|
||||
|
||||
let mut child = cmd.spawn()?;
|
||||
|
||||
// ✅ 保存 PID
|
||||
let pid = child.id();
|
||||
{
|
||||
*self.pid.lock().unwrap() = Some(pid);
|
||||
}
|
||||
|
||||
// ✅ 异步读取 stdout
|
||||
if let Some(out) = child.stdout.take() {
|
||||
let mut reader = BufReader::new(out);
|
||||
let mut line = String::new();
|
||||
thread::spawn(move || {
|
||||
while let Ok(n) = reader.read_line(&mut line) {
|
||||
if n == 0 {
|
||||
break;
|
||||
}
|
||||
on_stdout(line.clone());
|
||||
line.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if let Some(err) = child.stderr.take() {
|
||||
let mut reader = BufReader::new(err);
|
||||
let mut line = String::new();
|
||||
thread::spawn(move || {
|
||||
while let Ok(n) = reader.read_line(&mut line) {
|
||||
if n == 0 {
|
||||
break;
|
||||
}
|
||||
on_stderr(line.clone());
|
||||
line.clear();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
let child_arc = self.child.clone();
|
||||
*child_arc.lock().unwrap() = Some(child);
|
||||
|
||||
let pid_clone = self.pid.clone();
|
||||
thread::spawn(move || {
|
||||
if let Some(mut c) = child_arc.lock().unwrap().take() {
|
||||
match c.wait() {
|
||||
Ok(status) => {
|
||||
let code = status.code().unwrap_or(-1);
|
||||
*pid_clone.lock().unwrap() = None;
|
||||
on_exit(code);
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Error waiting for process: {e}");
|
||||
*pid_clone.lock().unwrap() = None;
|
||||
on_exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn kill(&self) -> std::io::Result<()> {
|
||||
let mut guard = self.child.lock().unwrap();
|
||||
if let Some(child) = guard.as_mut() {
|
||||
child.kill()?;
|
||||
Ok(())
|
||||
} else {
|
||||
Err(std::io::Error::new(
|
||||
std::io::ErrorKind::Other,
|
||||
"No running process",
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_alive(&self) -> bool {
|
||||
let mut guard = self.child.lock().unwrap();
|
||||
if let Some(child) = guard.as_mut() {
|
||||
match child.try_wait() {
|
||||
Ok(Some(_)) => false, // 已退出
|
||||
Ok(None) => true, // 仍在运行
|
||||
Err(_) => false,
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_pid(&self) -> Option<u32> {
|
||||
*self.pid.lock().unwrap()
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
#[tauri::command]
|
||||
pub fn add_group(
|
||||
group_name: String,
|
||||
group_subscribe_url: Option<String>,
|
||||
group_arguments: Option<String>,
|
||||
) {
|
||||
let message = match (&group_subscribe_url, &group_arguments) {
|
||||
(Some(url), Some(args)) => format!("add_group: {} {} {}", group_name, url, args),
|
||||
(Some(url), None) => format!("add_group: {} {}", group_name, url),
|
||||
(None, Some(args)) => format!("add_group: {} {}", group_name, args),
|
||||
(None, None) => format!("add_group: {}", group_name),
|
||||
};
|
||||
println!("{}", message);
|
||||
}
|
||||
@@ -1,12 +1,8 @@
|
||||
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
|
||||
|
||||
use crate::group::add_group;
|
||||
use crate::spary::spary_switch;
|
||||
use tauri_plugin_sql::{Migration, MigrationKind};
|
||||
mod exe;
|
||||
mod group;
|
||||
mod spary;
|
||||
mod cores;
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
@@ -31,6 +27,9 @@ pub fn run() {
|
||||
}
|
||||
];
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_process::init())
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.plugin(tauri_plugin_os::init())
|
||||
.plugin(tauri_plugin_fs::init())
|
||||
.plugin(
|
||||
tauri_plugin_sql::Builder::default()
|
||||
@@ -38,7 +37,7 @@ pub fn run() {
|
||||
.build(),
|
||||
)
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
.invoke_handler(tauri::generate_handler![spary_switch, add_group])
|
||||
.invoke_handler(tauri::generate_handler![spary_switch])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
mod entity;
|
||||
|
||||
fn main() {
|
||||
spary_lib::run()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user