mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-28 16:30:52 +08:00
Merge branch 'fix-linux-errors' into fix-migrate-tauri2-errors
* fix-linux-errors: chore: try to fix service not started on linux
This commit is contained in:
@@ -83,7 +83,7 @@ impl CoreManager {
|
||||
|
||||
// 服务模式
|
||||
if service::check_service().await.is_ok() {
|
||||
log::debug!(target: "app", "stop the core by service");
|
||||
log::info!(target: "app", "stop the core by service");
|
||||
service::stop_core_by_service().await?;
|
||||
}
|
||||
*running = false;
|
||||
@@ -94,7 +94,7 @@ impl CoreManager {
|
||||
pub async fn start_core(&self) -> Result<()> {
|
||||
let mut running = self.running.lock().await;
|
||||
if *running {
|
||||
log::debug!("core is running");
|
||||
log::info!("core is running");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ impl CoreManager {
|
||||
|
||||
// 服务模式
|
||||
if service::check_service().await.is_ok() {
|
||||
log::debug!(target: "app", "try to run core in service mode");
|
||||
log::info!(target: "app", "try to run core in service mode");
|
||||
service::run_core_by_service(&config_path).await?;
|
||||
*running = true;
|
||||
}
|
||||
@@ -126,7 +126,7 @@ impl CoreManager {
|
||||
bail!("invalid clash core name \"{clash_core}\"");
|
||||
}
|
||||
|
||||
log::debug!(target: "app", "change core to `{clash_core}`");
|
||||
log::info!(target: "app", "change core to `{clash_core}`");
|
||||
|
||||
Config::verge().draft().clash_core = Some(clash_core);
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ impl Drop for Hotkey {
|
||||
fn drop(&mut self) {
|
||||
let app_handle = handle::Handle::global().app_handle().unwrap();
|
||||
if let Err(e) = app_handle.global_shortcut().unregister_all() {
|
||||
log::error!("Error unregistering all hotkeys: {:?}", e);
|
||||
log::error!(target:"app", "Error unregistering all hotkeys: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ pub struct JsonResponse {
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub async fn reinstall_service() -> Result<()> {
|
||||
log::info!(target:"app", "reinstall service");
|
||||
|
||||
use deelevate::{PrivilegeLevel, Token};
|
||||
use runas::Command as RunasCommand;
|
||||
use std::os::windows::process::CommandExt;
|
||||
@@ -37,11 +39,11 @@ pub async fn reinstall_service() -> Result<()> {
|
||||
let uninstall_path = binary_path.with_file_name("uninstall-service.exe");
|
||||
|
||||
if !install_path.exists() {
|
||||
bail!("installer exe not found");
|
||||
bail!(format!("installer not found: {install_path:?}"));
|
||||
}
|
||||
|
||||
if !uninstall_path.exists() {
|
||||
bail!("uninstaller exe not found");
|
||||
bail!(format!("uninstaller not found: {uninstall_path:?}"));
|
||||
}
|
||||
|
||||
let token = Token::with_current_process()?;
|
||||
@@ -72,35 +74,39 @@ pub async fn reinstall_service() -> Result<()> {
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub async fn reinstall_service() -> Result<()> {
|
||||
log::info!(target:"app", "reinstall service");
|
||||
use users::get_effective_uid;
|
||||
|
||||
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");
|
||||
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!("installer not found");
|
||||
bail!(format!("installer not found: {install_path:?}"));
|
||||
}
|
||||
|
||||
if !uninstall_path.exists() {
|
||||
bail!("uninstaller not found");
|
||||
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 _ = match get_effective_uid() {
|
||||
0 => StdCommand::new(uninstall_path).status()?,
|
||||
_ => StdCommand::new("sudo")
|
||||
let elevator = crate::utils::help::linux_elevator();
|
||||
let status = match get_effective_uid() {
|
||||
0 => StdCommand::new(uninstall_shell).status()?,
|
||||
_ => StdCommand::new(elevator)
|
||||
.arg("sh")
|
||||
.arg("-c")
|
||||
.arg(uninstall_shell)
|
||||
.status()?,
|
||||
};
|
||||
log::info!(target:"app", "status code:{}", status.code().unwrap());
|
||||
|
||||
let elevator = crate::utils::help::linux_elevator();
|
||||
let status = match get_effective_uid() {
|
||||
0 => StdCommand::new(install_shell).status()?,
|
||||
_ => StdCommand::new("sudo")
|
||||
_ => StdCommand::new(elevator)
|
||||
.arg("sh")
|
||||
.arg("-c")
|
||||
.arg(install_shell)
|
||||
@@ -119,16 +125,18 @@ pub async fn reinstall_service() -> Result<()> {
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub async fn reinstall_service() -> Result<()> {
|
||||
log::info!(target:"app", "reinstall 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!("installer not found");
|
||||
bail!(format!("installer not found: {install_path:?}"));
|
||||
}
|
||||
|
||||
if !uninstall_path.exists() {
|
||||
bail!("uninstaller not found");
|
||||
bail!(format!("uninstaller not found: {uninstall_path:?}"));
|
||||
}
|
||||
|
||||
let install_shell: String = install_path.to_string_lossy().replace(" ", "\\ ");
|
||||
@@ -193,6 +201,8 @@ pub(super) async fn run_core_by_service(config_file: &PathBuf) -> Result<()> {
|
||||
map.insert("config_file", config_file);
|
||||
map.insert("log_file", log_path);
|
||||
|
||||
log::info!(target:"app", "start service: {:?}", map.clone());
|
||||
|
||||
let url = format!("{SERVICE_URL}/start_clash");
|
||||
let _ = reqwest::ClientBuilder::new()
|
||||
.no_proxy()
|
||||
|
||||
@@ -58,6 +58,7 @@ pub fn run() {
|
||||
}
|
||||
tauri::async_runtime::block_on(async move {
|
||||
resolve::resolve_setup(app).await;
|
||||
|
||||
#[cfg(not(target_os = "macos"))]
|
||||
{
|
||||
let argvs: Vec<String> = std::env::args().collect();
|
||||
|
||||
@@ -47,11 +47,9 @@ pub fn app_home_dir() -> Result<PathBuf> {
|
||||
let app_handle = handle::Handle::global().app_handle().unwrap();
|
||||
|
||||
match app_handle.path().data_dir() {
|
||||
Ok(dir) => {
|
||||
Ok(dir.join(APP_ID))
|
||||
}
|
||||
Ok(dir) => Ok(dir.join(APP_ID)),
|
||||
Err(e) => {
|
||||
log::error!("Failed to get the app home directory: {}", e);
|
||||
log::error!(target:"app", "Failed to get the app home directory: {}", e);
|
||||
Err(anyhow::anyhow!("Failed to get the app homedirectory"))
|
||||
}
|
||||
}
|
||||
@@ -61,11 +59,9 @@ pub fn app_home_dir() -> Result<PathBuf> {
|
||||
pub fn app_resources_dir() -> Result<PathBuf> {
|
||||
let app_handle = handle::Handle::global().app_handle().unwrap();
|
||||
match app_handle.path().resource_dir() {
|
||||
Ok(dir) => {
|
||||
Ok(dir.join("resources"))
|
||||
}
|
||||
Ok(dir) => Ok(dir.join("resources")),
|
||||
Err(e) => {
|
||||
log::error!("Failed to get the resource directory: {}", e);
|
||||
log::error!(target:"app", "Failed to get the resource directory: {}", e);
|
||||
Err(anyhow::anyhow!("Failed to get the resource directory"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +105,26 @@ pub fn open_file(app: tauri::AppHandle, path: PathBuf) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn linux_elevator() -> String {
|
||||
use std::process::Command;
|
||||
match Command::new("which").arg("sudo").output() {
|
||||
Ok(output) => {
|
||||
if !output.stdout.is_empty() {
|
||||
// Convert the output to a string slice
|
||||
if let Ok(path) = std::str::from_utf8(&output.stdout) {
|
||||
path.trim().to_string()
|
||||
} else {
|
||||
"sudo".to_string()
|
||||
}
|
||||
} else {
|
||||
"sudo".to_string()
|
||||
}
|
||||
}
|
||||
Err(_) => "sudo".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! error {
|
||||
($result: expr) => {
|
||||
|
||||
@@ -195,8 +195,10 @@ pub fn init_resources() -> Result<()> {
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
let file_list = ["Country.mmdb", "geoip.dat", "geosite.dat"];
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
#[cfg(target_os = "macos")]
|
||||
let file_list = ["Country.mmdb", "geoip.dat", "geosite.dat"];
|
||||
#[cfg(target_os = "linux")]
|
||||
let file_list: [&str; 0] = [];
|
||||
|
||||
// copy the resource file
|
||||
// if the source file is newer than the destination file, copy it over
|
||||
@@ -204,12 +206,13 @@ pub fn init_resources() -> Result<()> {
|
||||
let src_path = res_dir.join(file);
|
||||
let dest_path = app_dir.join(file);
|
||||
let test_dest_path = test_dir.join(file);
|
||||
log::info!(target: "app", "src_path: {src_path:?}, dest_path: {dest_path:?}");
|
||||
|
||||
let handle_copy = |dest: &PathBuf| {
|
||||
match fs::copy(&src_path, dest) {
|
||||
Ok(_) => log::debug!(target: "app", "resources copied '{file}'"),
|
||||
Err(err) => {
|
||||
log::error!(target: "app", "failed to copy resources '{file}', {err}")
|
||||
log::error!(target: "app", "failed to copy resources '{file}' to '{dest:?}', {err}")
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -43,12 +43,6 @@ pub async fn resolve_setup(app: &mut App) {
|
||||
handle::Handle::global().init(app.app_handle());
|
||||
VERSION.get_or_init(|| version.clone());
|
||||
|
||||
if service::check_service().await.is_err() {
|
||||
log_err!(service::reinstall_service().await);
|
||||
//延迟启动,避免闪屏
|
||||
std::thread::sleep(std::time::Duration::from_millis(1000));
|
||||
}
|
||||
|
||||
log_err!(init::init_config());
|
||||
log_err!(init::init_resources());
|
||||
log_err!(init::init_scheme());
|
||||
@@ -56,18 +50,22 @@ pub async fn resolve_setup(app: &mut App) {
|
||||
// 处理随机端口
|
||||
log_err!(resolve_random_port_config());
|
||||
// 启动核心
|
||||
log::trace!("init config");
|
||||
|
||||
log::trace!(target:"app", "init config");
|
||||
log_err!(Config::init_config().await);
|
||||
|
||||
log::trace!("launch core");
|
||||
if service::check_service().await.is_err() {
|
||||
log_err!(service::reinstall_service().await);
|
||||
std::thread::sleep(std::time::Duration::from_millis(1000));
|
||||
}
|
||||
|
||||
log::trace!(target: "app", "launch core");
|
||||
log_err!(CoreManager::global().init().await);
|
||||
|
||||
// setup a simple http server for singleton
|
||||
log::trace!("launch embed server");
|
||||
log::trace!(target: "app", "launch embed server");
|
||||
server::embed_server();
|
||||
|
||||
log::trace!("init system tray");
|
||||
log::trace!(target: "app", "init system tray");
|
||||
log_err!(tray::Tray::create_systray());
|
||||
|
||||
let silent_start = { Config::verge().data().enable_silent_start };
|
||||
@@ -160,7 +158,7 @@ pub fn create_window() {
|
||||
.latest()
|
||||
.window_is_maximized
|
||||
.unwrap_or(false);
|
||||
log::trace!("try to calculate the monitor size");
|
||||
log::trace!(target:"app", "try to calculate the monitor size");
|
||||
let center = (|| -> Result<bool> {
|
||||
let mut center = false;
|
||||
let monitor = win.current_monitor()?.ok_or(anyhow::anyhow!(""))?;
|
||||
@@ -220,7 +218,7 @@ pub fn save_window_size_position(save_to_file: bool) -> Result<()> {
|
||||
}
|
||||
|
||||
pub async fn resolve_scheme(param: String) -> Result<()> {
|
||||
log::info!("received deep link: {}", param);
|
||||
log::info!(target:"app", "received deep link: {}", param);
|
||||
|
||||
let app_handle = handle::Handle::global().app_handle().unwrap();
|
||||
|
||||
|
||||
@@ -18,7 +18,14 @@
|
||||
"conflicts": ["clash-verge"],
|
||||
"obsoletes": ["clash-verge"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"externalBin": [
|
||||
"./resources/clash-verge-service",
|
||||
"./resources/install-service",
|
||||
"./resources/uninstall-service",
|
||||
"./sidecar/verge-mihomo",
|
||||
"./sidecar/verge-mihomo-alpha"
|
||||
]
|
||||
},
|
||||
"app": {
|
||||
"trayIcon": {
|
||||
|
||||
Reference in New Issue
Block a user