fix: change service installer and uninstaller

This commit is contained in:
GyDi 2022-04-27 15:46:44 +08:00 committed by GitHub
parent 77ef3847ce
commit f88989bd4b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 58 additions and 49 deletions

View File

@ -143,20 +143,26 @@ async function resolveService() {
if (platform !== "win32") return;
const url =
"https://github.com/zzzgydi/clash-verge-service/releases/download/latest/clash-verge-service.exe";
const binName = "clash-verge-service.exe";
const resDir = path.join(cwd, "src-tauri/resources");
const targetPath = path.join(resDir, binName);
const repo =
"https://github.com/zzzgydi/clash-verge-service/releases/download/latest";
async function help(bin) {
const targetPath = path.join(resDir, bin);
if (!FORCE && (await fs.pathExists(targetPath))) return;
await fs.mkdirp(resDir);
const url = `${repo}/${bin}`;
await downloadFile(url, targetPath);
}
console.log(`[INFO]: resolve ${binName} finished`);
await fs.mkdirp(resDir);
await help("clash-verge-service.exe");
await help("install-service.exe");
await help("uninstall-service.exe");
console.log(`[INFO]: resolve Service finished`);
}
/**

View File

@ -258,20 +258,20 @@ pub mod service {
#[tauri::command]
pub async fn check_service() -> Result<JsonResponse, String> {
wrap_err!(crate::core::Service::check_service().await)
// no log
match crate::core::Service::check_service().await {
Ok(res) => Ok(res),
Err(err) => Err(err.to_string()),
}
}
#[tauri::command]
pub async fn install_service() -> Result<(), String> {
log_if_err!(crate::core::Service::install_service().await);
let ret = wrap_err!(crate::core::Service::start_service().await);
log::info!("clash verge service started successfully");
ret
wrap_err!(crate::core::Service::install_service().await)
}
#[tauri::command]
pub async fn uninstall_service() -> Result<(), String> {
log_if_err!(crate::core::Service::stop_service().await);
wrap_err!(crate::core::Service::uninstall_service().await)
}
}

View File

@ -191,8 +191,9 @@ pub mod win_service {
use super::*;
use anyhow::Context;
use deelevate::{PrivilegeLevel, Token};
use runas::Command as RunasCommond;
use std::{env::current_exe, process::Command as StdCommond};
use runas::Command as RunasCommand;
use std::os::windows::process::CommandExt;
use std::{env::current_exe, process::Command as StdCommand};
const SERVICE_NAME: &str = "clash_verge_service";
@ -217,61 +218,63 @@ pub mod win_service {
/// 该函数应该在协程或者线程中执行避免UAC弹窗阻塞主线程
pub async fn install_service() -> Result<()> {
let binary_path = dirs::service_path();
let arg = format!("binpath={}", binary_path.as_os_str().to_string_lossy());
let install_path = binary_path.with_file_name("install-service.exe");
if !install_path.exists() {
bail!("installer exe not found");
}
let token = Token::with_current_process()?;
let level = token.privilege_level()?;
let args = [
"create",
SERVICE_NAME,
arg.as_str(),
"type=own",
"start=AUTO",
"displayname=Clash Verge Service",
];
let status = match level {
PrivilegeLevel::NotPrivileged => RunasCommond::new("sc").args(&args).status()?,
_ => StdCommond::new("sc").args(&args).status()?,
PrivilegeLevel::NotPrivileged => RunasCommand::new(install_path).status()?,
_ => StdCommand::new(install_path)
.creation_flags(0x08000000)
.status()?,
};
if status.success() {
return Ok(());
}
if status.code() == Some(1073i32) {
bail!("clash verge service is installed");
}
if !status.success() {
bail!(
"failed to install service with status {}",
status.code().unwrap()
)
);
}
Ok(())
}
/// Uninstall the Clash Verge Service
/// 该函数应该在协程或者线程中执行避免UAC弹窗阻塞主线程
pub async fn uninstall_service() -> Result<()> {
let binary_path = dirs::service_path();
let uninstall_path = binary_path.with_file_name("uninstall-service.exe");
if !uninstall_path.exists() {
bail!("uninstaller exe not found");
}
let token = Token::with_current_process()?;
let level = token.privilege_level()?;
let args = ["delete", SERVICE_NAME];
let status = match level {
PrivilegeLevel::NotPrivileged => RunasCommond::new("sc").args(&args).status()?,
_ => StdCommond::new("sc").args(&args).status()?,
PrivilegeLevel::NotPrivileged => RunasCommand::new(uninstall_path).status()?,
_ => StdCommand::new(uninstall_path)
.creation_flags(0x08000000)
.status()?,
};
match status.success() {
true => Ok(()),
false => bail!(
if !status.success() {
bail!(
"failed to uninstall service with status {}",
status.code().unwrap()
),
}
);
}
Ok(())
}
/// [deprecated]
/// start service
/// 该函数应该在协程或者线程中执行避免UAC弹窗阻塞主线程
pub async fn start_service() -> Result<()> {
@ -281,8 +284,8 @@ pub mod win_service {
let args = ["start", SERVICE_NAME];
let status = match level {
PrivilegeLevel::NotPrivileged => RunasCommond::new("sc").args(&args).status()?,
_ => StdCommond::new("sc").args(&args).status()?,
PrivilegeLevel::NotPrivileged => RunasCommand::new("sc").args(&args).status()?,
_ => StdCommand::new("sc").args(&args).status()?,
};
match status.success() {