chore: try to fix service not started on linux

This commit is contained in:
huzibaca
2024-10-18 22:30:29 +08:00
parent 770f031b8b
commit ee78b7898b
12 changed files with 396 additions and 54 deletions

View File

@@ -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);

View File

@@ -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);
}
}
}

View File

@@ -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()

View File

@@ -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();

View File

@@ -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"))
}
}

View File

@@ -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) => {

View File

@@ -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}")
}
};
};

View File

@@ -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();

View File

@@ -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": {