From c733bda6c31619f67ae39fc9ed1c0254ede03d9d Mon Sep 17 00:00:00 2001 From: GyDi Date: Thu, 21 Apr 2022 21:28:44 +0800 Subject: [PATCH] test: windows service --- src-tauri/Cargo.lock | 45 ++++++++++++++++++++++++++++ src-tauri/Cargo.toml | 1 + src-tauri/src/core/service.rs | 55 +++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+) diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index d123d20..94b50a6 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -502,6 +502,7 @@ dependencies = [ "which", "window-shadows", "window-vibrancy", + "windows-service", "winreg", ] @@ -970,6 +971,20 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "err-derive" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34a887c8df3ed90498c1c437ce21f211c8e27672921a8ffa293cb8d6d4caa9e" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "rustversion", + "syn", + "synstructure", +] + [[package]] name = "event-listener" version = "2.5.2" @@ -3476,6 +3491,18 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + [[package]] name = "system-deps" version = "3.2.0" @@ -4428,6 +4455,12 @@ dependencies = [ "libc", ] +[[package]] +name = "widestring" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c168940144dd21fd8046987c16a46a33d5fc84eec29ef9dcddc2ac9e31526b7c" + [[package]] name = "wildmatch" version = "2.1.0" @@ -4523,6 +4556,18 @@ dependencies = [ "windows_reader", ] +[[package]] +name = "windows-service" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c643e10139d127d30d6d753398c8a6f0a43532e8370f6c9d29ebbff29b984ab" +dependencies = [ + "bitflags", + "err-derive", + "widestring", + "winapi", +] + [[package]] name = "windows-sys" version = "0.32.0" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index b1b03ff..18bad1e 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -39,6 +39,7 @@ port_scanner = "0.1.5" [target.'cfg(windows)'.dependencies] winreg = { version = "0.10", features = ["transactions"] } +windows-service = "0.4.0" [features] default = ["custom-protocol"] diff --git a/src-tauri/src/core/service.rs b/src-tauri/src/core/service.rs index 468037e..96b8f4c 100644 --- a/src-tauri/src/core/service.rs +++ b/src-tauri/src/core/service.rs @@ -57,6 +57,61 @@ impl Service { self.start() } + #[cfg(windows)] + pub fn install(&mut self) -> Result<()> { + use std::{env::current_exe, ffi::OsString}; + use windows_service::{ + service::{ServiceAccess, ServiceErrorControl, ServiceInfo, ServiceStartType, ServiceType}, + service_manager::{ServiceManager, ServiceManagerAccess}, + }; + + let manager_access = ServiceManagerAccess::CONNECT | ServiceManagerAccess::CREATE_SERVICE; + let service_manager = ServiceManager::local_computer(None::<&str>, manager_access)?; + + let service_binary_path = current_exe().unwrap().with_file_name("clash.exe"); + + let service_info = ServiceInfo { + name: OsString::from("clash_verge_core"), + display_name: OsString::from("Clash Verge Core"), + service_type: ServiceType::OWN_PROCESS, + start_type: ServiceStartType::OnDemand, + error_control: ServiceErrorControl::Normal, + executable_path: service_binary_path, + launch_arguments: vec![], + dependencies: vec![], + account_name: None, // run as System + account_password: None, + }; + + let service = service_manager.create_service(&service_info, ServiceAccess::CHANGE_CONFIG)?; + service.set_description("Clash Core Service installed by Clash Verge")?; + + Ok(()) + } + + #[cfg(windows)] + pub fn check_status(&mut self) -> Result { + use windows_service::{ + service::{ServiceAccess, ServiceState}, + service_manager::{ServiceManager, ServiceManagerAccess}, + }; + + let manager_access = ServiceManagerAccess::CONNECT; + let service_manager = ServiceManager::local_computer(None::<&str>, manager_access)?; + + let service_access = ServiceAccess::QUERY_STATUS; // | ServiceAccess::STOP | ServiceAccess::DELETE; + let service = service_manager.open_service("clash_verge_core", service_access)?; + + let service_status = service.query_status()?; + + Ok(format!("{:?}", service_status.current_state)) + } + + #[cfg(windows)] + pub fn start_service(&mut self) -> Result<()> { + Ok(()) + } + /// update clash config /// using PUT methods pub fn set_config(&self, info: ClashInfo, config: Mapping, notice: Notice) -> Result<()> {