mirror of
https://github.com/clash-verge-rev/clash-verge-rev
synced 2025-05-04 21:37:33 +08:00
refactor: replace println with logging in core validation and tray quit function
This commit is contained in:
parent
0ec4f46052
commit
98d3a48710
@ -184,23 +184,22 @@ impl CoreManager {
|
||||
async fn validate_config_internal(&self, config_path: &str) -> Result<(bool, String)> {
|
||||
// 检查程序是否正在退出,如果是则跳过验证
|
||||
if handle::Handle::global().is_exiting() {
|
||||
println!("[core配置验证] 应用正在退出,跳过验证");
|
||||
logging!(info, Type::Core, true, "应用正在退出,跳过验证");
|
||||
return Ok((true, String::new()));
|
||||
}
|
||||
|
||||
println!("[core配置验证] 开始验证配置文件: {}", config_path);
|
||||
logging!(info, Type::Core, true, "开始验证配置文件: {}", config_path);
|
||||
|
||||
let clash_core = { Config::verge().latest().clash_core.clone() };
|
||||
let clash_core = clash_core.unwrap_or("verge-mihomo".into());
|
||||
println!("[core配置验证] 使用内核: {}", clash_core);
|
||||
logging!(info, Type::Core, true, "使用内核: {}", clash_core);
|
||||
|
||||
let app_handle = handle::Handle::global().app_handle().unwrap();
|
||||
let test_dir = dirs::app_home_dir()?.join("test");
|
||||
let test_dir = dirs::path_to_str(&test_dir)?;
|
||||
println!("[core配置验证] 测试目录: {}", test_dir);
|
||||
logging!(info, Type::Core, true, "测试目录: {}", test_dir);
|
||||
|
||||
// 使用子进程运行clash验证配置
|
||||
println!("[core配置验证] 运行子进程验证配置");
|
||||
let output = app_handle
|
||||
.shell()
|
||||
.sidecar(clash_core)?
|
||||
@ -216,18 +215,14 @@ impl CoreManager {
|
||||
let has_error =
|
||||
!output.status.success() || error_keywords.iter().any(|&kw| stderr.contains(kw));
|
||||
|
||||
println!("\n[core配置验证] -------- 验证结果 --------");
|
||||
println!("[core配置验证] 进程退出状态: {:?}", output.status);
|
||||
logging!(info, Type::Core, true, "-------- 验证结果 --------");
|
||||
|
||||
if !stderr.is_empty() {
|
||||
println!("[core配置验证] stderr输出:\n{}", stderr);
|
||||
}
|
||||
if !stdout.is_empty() {
|
||||
println!("[core配置验证] stdout输出:\n{}", stdout);
|
||||
logging!(info, Type::Core, true, "stderr输出:\n{}", stderr);
|
||||
}
|
||||
|
||||
if has_error {
|
||||
println!("[core配置验证] 发现错误,开始处理错误信息");
|
||||
logging!(info, Type::Core, true, "发现错误,开始处理错误信息");
|
||||
let error_msg = if !stdout.is_empty() {
|
||||
stdout.to_string()
|
||||
} else if !stderr.is_empty() {
|
||||
@ -238,11 +233,11 @@ impl CoreManager {
|
||||
"验证进程被终止".to_string()
|
||||
};
|
||||
|
||||
println!("[core配置验证] -------- 验证结束 --------\n");
|
||||
logging!(info, Type::Core, true, "-------- 验证结束 --------\n");
|
||||
Ok((false, error_msg)) // 返回错误消息给调用者处理
|
||||
} else {
|
||||
println!("[core配置验证] 验证成功");
|
||||
println!("[core配置验证] -------- 验证结束 --------\n");
|
||||
logging!(info, Type::Core, true, "验证成功");
|
||||
logging!(info, Type::Core, true, "-------- 验证结束 --------\n");
|
||||
Ok((true, String::new()))
|
||||
}
|
||||
}
|
||||
|
@ -119,43 +119,56 @@ pub struct VersionJsonResponse {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub async fn reinstall_service() -> Result<()> {
|
||||
log::info!(target:"app", "reinstall service");
|
||||
|
||||
// 获取当前服务状态
|
||||
let mut service_state = ServiceState::get();
|
||||
|
||||
// 检查是否允许重装
|
||||
if !service_state.can_reinstall() {
|
||||
log::warn!(target:"app", "service reinstall rejected: cooldown period or max attempts reached");
|
||||
bail!("Service reinstallation is rate limited. Please try again later.");
|
||||
}
|
||||
pub async fn uninstall_service() -> Result<()> {
|
||||
logging!(info, Type::Service, true, "uninstall service");
|
||||
|
||||
use deelevate::{PrivilegeLevel, Token};
|
||||
use runas::Command as RunasCommand;
|
||||
use std::os::windows::process::CommandExt;
|
||||
|
||||
let binary_path = dirs::service_path()?;
|
||||
let install_path = binary_path.with_file_name("install-service.exe");
|
||||
let uninstall_path = binary_path.with_file_name("uninstall-service.exe");
|
||||
|
||||
if !install_path.exists() {
|
||||
bail!(format!("installer not found: {install_path:?}"));
|
||||
}
|
||||
|
||||
if !uninstall_path.exists() {
|
||||
bail!(format!("uninstaller not found: {uninstall_path:?}"));
|
||||
}
|
||||
|
||||
let token = Token::with_current_process()?;
|
||||
let level = token.privilege_level()?;
|
||||
let _ = match level {
|
||||
let status = match level {
|
||||
PrivilegeLevel::NotPrivileged => RunasCommand::new(uninstall_path).show(false).status()?,
|
||||
_ => StdCommand::new(uninstall_path)
|
||||
.creation_flags(0x08000000)
|
||||
.status()?,
|
||||
};
|
||||
|
||||
if !status.success() {
|
||||
bail!(
|
||||
"failed to uninstall service with status {}",
|
||||
status.code().unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub async fn install_service() -> Result<()> {
|
||||
logging!(info, Type::Service, true, "install service");
|
||||
|
||||
use deelevate::{PrivilegeLevel, Token};
|
||||
use runas::Command as RunasCommand;
|
||||
use std::os::windows::process::CommandExt;
|
||||
|
||||
let binary_path = dirs::service_path()?;
|
||||
let install_path = binary_path.with_file_name("install-service.exe");
|
||||
|
||||
if !install_path.exists() {
|
||||
bail!(format!("installer not found: {install_path:?}"));
|
||||
}
|
||||
|
||||
let token = Token::with_current_process()?;
|
||||
let level = token.privilege_level()?;
|
||||
let status = match level {
|
||||
PrivilegeLevel::NotPrivileged => RunasCommand::new(install_path).show(false).status()?,
|
||||
_ => StdCommand::new(install_path)
|
||||
@ -164,41 +177,73 @@ pub async fn reinstall_service() -> Result<()> {
|
||||
};
|
||||
|
||||
if !status.success() {
|
||||
let error = format!(
|
||||
bail!(
|
||||
"failed to install service with status {}",
|
||||
status.code().unwrap()
|
||||
);
|
||||
service_state.last_error = Some(error.clone());
|
||||
service_state.save()?;
|
||||
bail!(error);
|
||||
}
|
||||
|
||||
// 记录安装信息并保存
|
||||
service_state.record_install();
|
||||
service_state.last_error = None;
|
||||
service_state.save()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_os = "windows")]
|
||||
pub async fn reinstall_service() -> Result<()> {
|
||||
log::info!(target:"app", "reinstall service");
|
||||
logging!(info, Type::Service, true, "reinstall service");
|
||||
|
||||
// 获取当前服务状态
|
||||
let mut service_state = ServiceState::get();
|
||||
|
||||
// 检查是否允许重装
|
||||
if !service_state.can_reinstall() {
|
||||
logging!(
|
||||
warn,
|
||||
Type::Service,
|
||||
true,
|
||||
"service reinstall rejected: cooldown period or max attempts reached"
|
||||
);
|
||||
bail!("Service reinstallation is rate limited. Please try again later.");
|
||||
}
|
||||
|
||||
// 先卸载服务
|
||||
if let Err(err) = uninstall_service().await {
|
||||
logging!(
|
||||
warn,
|
||||
Type::Service,
|
||||
true,
|
||||
"failed to uninstall service: {}",
|
||||
err
|
||||
);
|
||||
}
|
||||
|
||||
// 再安装服务
|
||||
match install_service().await {
|
||||
Ok(_) => {
|
||||
// 记录安装信息并保存
|
||||
service_state.record_install();
|
||||
service_state.last_error = None;
|
||||
service_state.save()?;
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => {
|
||||
let error = format!("failed to install service: {}", err);
|
||||
service_state.last_error = Some(error.clone());
|
||||
service_state.save()?;
|
||||
bail!(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub async fn uninstall_service() -> Result<()> {
|
||||
logging!(info, Type::Service, true, "uninstall service");
|
||||
use users::get_effective_uid;
|
||||
|
||||
let install_path = tauri::utils::platform::current_exe()?.with_file_name("install-service");
|
||||
|
||||
let uninstall_path = tauri::utils::platform::current_exe()?.with_file_name("uninstall-service");
|
||||
|
||||
if !install_path.exists() {
|
||||
bail!(format!("installer not found: {install_path:?}"));
|
||||
}
|
||||
|
||||
if !uninstall_path.exists() {
|
||||
bail!(format!("uninstaller not found: {uninstall_path:?}"));
|
||||
}
|
||||
|
||||
let install_shell: String = install_path.to_string_lossy().replace(" ", "\\ ");
|
||||
let uninstall_shell: String = uninstall_path.to_string_lossy().replace(" ", "\\ ");
|
||||
|
||||
let elevator = crate::utils::help::linux_elevator();
|
||||
@ -210,8 +255,38 @@ pub async fn reinstall_service() -> Result<()> {
|
||||
.arg(uninstall_shell)
|
||||
.status()?,
|
||||
};
|
||||
log::info!(target:"app", "status code:{}", status.code().unwrap());
|
||||
logging!(
|
||||
info,
|
||||
Type::Service,
|
||||
true,
|
||||
"uninstall status code:{}",
|
||||
status.code().unwrap()
|
||||
);
|
||||
|
||||
if !status.success() {
|
||||
bail!(
|
||||
"failed to uninstall service with status {}",
|
||||
status.code().unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub async fn install_service() -> Result<()> {
|
||||
logging!(info, Type::Service, true, "install service");
|
||||
use users::get_effective_uid;
|
||||
|
||||
let install_path = tauri::utils::platform::current_exe()?.with_file_name("install-service");
|
||||
|
||||
if !install_path.exists() {
|
||||
bail!(format!("installer not found: {install_path:?}"));
|
||||
}
|
||||
|
||||
let install_shell: String = install_path.to_string_lossy().replace(" ", "\\ ");
|
||||
|
||||
let elevator = crate::utils::help::linux_elevator();
|
||||
let status = match get_effective_uid() {
|
||||
0 => StdCommand::new(install_shell).status()?,
|
||||
_ => StdCommand::new(elevator.clone())
|
||||
@ -220,6 +295,13 @@ pub async fn reinstall_service() -> Result<()> {
|
||||
.arg(install_shell)
|
||||
.status()?,
|
||||
};
|
||||
logging!(
|
||||
info,
|
||||
Type::Service,
|
||||
true,
|
||||
"install status code:{}",
|
||||
status.code().unwrap()
|
||||
);
|
||||
|
||||
if !status.success() {
|
||||
bail!(
|
||||
@ -228,42 +310,113 @@ pub async fn reinstall_service() -> Result<()> {
|
||||
);
|
||||
}
|
||||
|
||||
// 记录安装信息并保存
|
||||
let mut service_state = ServiceState::get();
|
||||
service_state.record_install();
|
||||
service_state.last_error = None;
|
||||
service_state.save()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[cfg(target_os = "linux")]
|
||||
pub async fn reinstall_service() -> Result<()> {
|
||||
logging!(info, Type::Service, true, "reinstall service");
|
||||
|
||||
// 获取当前服务状态
|
||||
let mut service_state = ServiceState::get();
|
||||
|
||||
// 检查是否允许重装
|
||||
if !service_state.can_reinstall() {
|
||||
logging!(
|
||||
warn,
|
||||
Type::Service,
|
||||
true,
|
||||
"service reinstall rejected: cooldown period or max attempts reached"
|
||||
);
|
||||
bail!("Service reinstallation is rate limited. Please try again later.");
|
||||
}
|
||||
|
||||
// 先卸载服务
|
||||
if let Err(err) = uninstall_service().await {
|
||||
logging!(
|
||||
warn,
|
||||
Type::Service,
|
||||
true,
|
||||
"failed to uninstall service: {}",
|
||||
err
|
||||
);
|
||||
}
|
||||
|
||||
// 再安装服务
|
||||
match install_service().await {
|
||||
Ok(_) => {
|
||||
// 记录安装信息并保存
|
||||
service_state.record_install();
|
||||
service_state.last_error = None;
|
||||
service_state.save()?;
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => {
|
||||
let error = format!("failed to install service: {}", err);
|
||||
service_state.last_error = Some(error.clone());
|
||||
service_state.save()?;
|
||||
bail!(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub async fn uninstall_service() -> Result<()> {
|
||||
use crate::utils::i18n::t;
|
||||
|
||||
log::info!(target:"app", "reinstall service");
|
||||
logging!(info, Type::Service, true, "uninstall service");
|
||||
|
||||
let binary_path = dirs::service_path()?;
|
||||
let install_path = binary_path.with_file_name("install-service");
|
||||
let uninstall_path = binary_path.with_file_name("uninstall-service");
|
||||
|
||||
if !install_path.exists() {
|
||||
bail!(format!("installer not found: {install_path:?}"));
|
||||
}
|
||||
|
||||
if !uninstall_path.exists() {
|
||||
bail!(format!("uninstaller not found: {uninstall_path:?}"));
|
||||
}
|
||||
|
||||
let install_shell: String = install_path.to_string_lossy().into_owned();
|
||||
let uninstall_shell: String = uninstall_path.to_string_lossy().into_owned();
|
||||
|
||||
let prompt = t("Service Administrator Prompt");
|
||||
let command = format!(
|
||||
r#"do shell script "sudo '{uninstall_shell}' && sudo '{install_shell}'" with administrator privileges with prompt "{prompt}""#
|
||||
r#"do shell script "sudo '{uninstall_shell}'" with administrator privileges with prompt "{prompt}""#
|
||||
);
|
||||
|
||||
log::debug!(target: "app", "command: {}", command);
|
||||
logging!(debug, Type::Service, true, "uninstall command: {}", command);
|
||||
|
||||
let status = StdCommand::new("osascript")
|
||||
.args(vec!["-e", &command])
|
||||
.status()?;
|
||||
|
||||
if !status.success() {
|
||||
bail!(
|
||||
"failed to uninstall service with status {}",
|
||||
status.code().unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub async fn install_service() -> Result<()> {
|
||||
use crate::utils::i18n::t;
|
||||
|
||||
logging!(info, Type::Service, true, "install service");
|
||||
|
||||
let binary_path = dirs::service_path()?;
|
||||
let install_path = binary_path.with_file_name("install-service");
|
||||
|
||||
if !install_path.exists() {
|
||||
bail!(format!("installer not found: {install_path:?}"));
|
||||
}
|
||||
|
||||
let install_shell: String = install_path.to_string_lossy().into_owned();
|
||||
|
||||
let prompt = t("Service Administrator Prompt");
|
||||
let command = format!(
|
||||
r#"do shell script "sudo '{install_shell}'" with administrator privileges with prompt "{prompt}""#
|
||||
);
|
||||
|
||||
logging!(debug, Type::Service, true, "install command: {}", command);
|
||||
|
||||
let status = StdCommand::new("osascript")
|
||||
.args(vec!["-e", &command])
|
||||
@ -276,15 +429,56 @@ pub async fn reinstall_service() -> Result<()> {
|
||||
);
|
||||
}
|
||||
|
||||
// 记录安装信息并保存
|
||||
let mut service_state = ServiceState::get();
|
||||
service_state.record_install();
|
||||
service_state.last_error = None;
|
||||
service_state.save()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub async fn reinstall_service() -> Result<()> {
|
||||
logging!(info, Type::Service, true, "reinstall service");
|
||||
|
||||
// 获取当前服务状态
|
||||
let mut service_state = ServiceState::get();
|
||||
|
||||
// 检查是否允许重装
|
||||
if !service_state.can_reinstall() {
|
||||
logging!(
|
||||
warn,
|
||||
Type::Service,
|
||||
true,
|
||||
"service reinstall rejected: cooldown period or max attempts reached"
|
||||
);
|
||||
bail!("Service reinstallation is rate limited. Please try again later.");
|
||||
}
|
||||
|
||||
// 先卸载服务
|
||||
if let Err(err) = uninstall_service().await {
|
||||
logging!(
|
||||
warn,
|
||||
Type::Service,
|
||||
true,
|
||||
"failed to uninstall service: {}",
|
||||
err
|
||||
);
|
||||
}
|
||||
|
||||
// 再安装服务
|
||||
match install_service().await {
|
||||
Ok(_) => {
|
||||
// 记录安装信息并保存
|
||||
service_state.record_install();
|
||||
service_state.last_error = None;
|
||||
service_state.save()?;
|
||||
Ok(())
|
||||
}
|
||||
Err(err) => {
|
||||
let error = format!("failed to install service: {}", err);
|
||||
service_state.last_error = Some(error.clone());
|
||||
service_state.save()?;
|
||||
bail!(error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// check the windows service status
|
||||
pub async fn check_service() -> Result<JsonResponse> {
|
||||
let url = format!("{SERVICE_URL}/get_clash");
|
||||
|
@ -665,7 +665,6 @@ fn on_menu_event(_: &AppHandle, event: MenuEvent) {
|
||||
"restart_app" => feat::restart_app(),
|
||||
"entry_lightweight_mode" => entry_lightweight_mode(),
|
||||
"quit" => {
|
||||
println!("quit");
|
||||
feat::quit(Some(0));
|
||||
}
|
||||
id if id.starts_with("profiles_") => {
|
||||
|
@ -1,6 +1,12 @@
|
||||
use crate::{
|
||||
config::{Config, IVerge},
|
||||
core::handle,
|
||||
core::{
|
||||
handle,
|
||||
service::{install_service, is_service_available, reinstall_service},
|
||||
CoreManager,
|
||||
},
|
||||
logging, logging_error,
|
||||
utils::logging::Type,
|
||||
};
|
||||
use std::env;
|
||||
use tauri_plugin_clipboard_manager::ClipboardExt;
|
||||
@ -28,6 +34,19 @@ pub fn toggle_system_proxy() {
|
||||
|
||||
/// Toggle TUN mode on/off
|
||||
pub fn toggle_tun_mode(not_save_file: Option<bool>) {
|
||||
// tauri::async_runtime::spawn(async move {
|
||||
// logging!(
|
||||
// info,
|
||||
// Type::Service,
|
||||
// true,
|
||||
// "Toggle TUN mode need install service"
|
||||
// );
|
||||
// if is_service_available().await.is_err() {
|
||||
// logging_error!(Type::Service, true, install_service().await);
|
||||
// }
|
||||
// logging_error!(Type::Core, true, CoreManager::global().restart_core().await);
|
||||
// });
|
||||
|
||||
let enable = Config::verge().data().enable_tun_mode;
|
||||
let enable = enable.unwrap_or(false);
|
||||
|
||||
|
@ -1,7 +1,12 @@
|
||||
#[cfg(target_os = "macos")]
|
||||
use crate::AppHandleManager;
|
||||
use crate::{
|
||||
config::{Config, IVerge, PrfItem}, core::*, log_err, module::lightweight, utils::{error, init, server}, wrap_err
|
||||
config::{Config, IVerge, PrfItem},
|
||||
core::*,
|
||||
log_err,
|
||||
module::lightweight,
|
||||
utils::{error, init, server},
|
||||
wrap_err,
|
||||
};
|
||||
use anyhow::{bail, Result};
|
||||
use once_cell::sync::OnceCell;
|
||||
@ -58,7 +63,7 @@ pub async fn resolve_setup(app: &mut App) {
|
||||
log_err!(Config::init_config().await);
|
||||
|
||||
if service::check_service().await.is_err() {
|
||||
match service::reinstall_service().await {
|
||||
match service::install_service().await {
|
||||
Ok(_) => {
|
||||
log::info!(target:"app", "install service susccess.");
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
|
@ -40,11 +40,18 @@ const SettingSystem = ({ onError }: Props) => {
|
||||
"getRunningMode",
|
||||
getRunningMode,
|
||||
);
|
||||
const { data: autoLaunchEnabled } = useSWR("getAutoLaunchStatus", getAutoLaunchStatus);
|
||||
const { data: autoLaunchEnabled } = useSWR(
|
||||
"getAutoLaunchStatus",
|
||||
getAutoLaunchStatus,
|
||||
);
|
||||
|
||||
// 当实际自启动状态与配置不同步时更新配置
|
||||
useEffect(() => {
|
||||
if (autoLaunchEnabled !== undefined && verge && verge.enable_auto_launch !== autoLaunchEnabled) {
|
||||
if (
|
||||
autoLaunchEnabled !== undefined &&
|
||||
verge &&
|
||||
verge.enable_auto_launch !== autoLaunchEnabled
|
||||
) {
|
||||
// 静默更新配置,不触发UI刷新
|
||||
mutateVerge({ ...verge, enable_auto_launch: autoLaunchEnabled }, false);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user