feat: supports auto launch on macos and windows
This commit is contained in:
parent
3c3d77fbea
commit
cc0e930d34
@ -1,6 +1,6 @@
|
|||||||
use crate::utils::{config, dirs, startup, sysopt::SysProxyConfig};
|
use crate::utils::{config, dirs, sysopt::SysProxyConfig};
|
||||||
|
use auto_launch::{AutoLaunch, AutoLaunchBuilder};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::path::PathBuf;
|
|
||||||
use tauri::api::path::resource_dir;
|
use tauri::api::path::resource_dir;
|
||||||
|
|
||||||
/// ### `verge.yaml` schema
|
/// ### `verge.yaml` schema
|
||||||
@ -14,7 +14,7 @@ pub struct VergeConfig {
|
|||||||
pub theme_blur: Option<bool>,
|
pub theme_blur: Option<bool>,
|
||||||
|
|
||||||
/// can the app auto startup
|
/// can the app auto startup
|
||||||
pub enable_self_startup: Option<bool>,
|
pub enable_auto_launch: Option<bool>,
|
||||||
|
|
||||||
/// set system proxy
|
/// set system proxy
|
||||||
pub enable_system_proxy: Option<bool>,
|
pub enable_system_proxy: Option<bool>,
|
||||||
@ -49,7 +49,7 @@ pub struct Verge {
|
|||||||
|
|
||||||
pub cur_sysproxy: Option<SysProxyConfig>,
|
pub cur_sysproxy: Option<SysProxyConfig>,
|
||||||
|
|
||||||
pub exe_path: Option<PathBuf>,
|
pub auto_launch: Option<AutoLaunch>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Verge {
|
impl Default for Verge {
|
||||||
@ -64,7 +64,7 @@ impl Verge {
|
|||||||
config: VergeConfig::new(),
|
config: VergeConfig::new(),
|
||||||
old_sysproxy: None,
|
old_sysproxy: None,
|
||||||
cur_sysproxy: None,
|
cur_sysproxy: None,
|
||||||
exe_path: None,
|
auto_launch: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,53 +101,61 @@ impl Verge {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// set the exe_path
|
/// init the auto launch
|
||||||
pub fn set_exe_path(&mut self, package_info: &tauri::PackageInfo) {
|
pub fn init_launch(&mut self, package_info: &tauri::PackageInfo) {
|
||||||
let exe = if cfg!(target_os = "windows") {
|
let app_name = "clash-verge";
|
||||||
"clash-verge.exe"
|
let app_path = get_app_path(app_name);
|
||||||
} else {
|
let app_path = resource_dir(package_info).unwrap().join(app_path);
|
||||||
"clash-verge"
|
let app_path = app_path.as_os_str().to_str().unwrap();
|
||||||
};
|
|
||||||
let path = resource_dir(package_info).unwrap().join(exe);
|
let auto = AutoLaunchBuilder::new()
|
||||||
self.exe_path = Some(path);
|
.set_app_name(app_name)
|
||||||
|
.set_app_path(app_path)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
self.auto_launch = Some(auto);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// sync the startup when run the app
|
/// sync the startup when run the app
|
||||||
pub fn sync_startup(&self) -> Result<(), String> {
|
pub fn sync_launch(&self) -> Result<(), String> {
|
||||||
let enable = self.config.enable_self_startup.clone().unwrap_or(false);
|
let enable = self.config.enable_auto_launch.clone().unwrap_or(false);
|
||||||
|
|
||||||
if !enable {
|
if !enable {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
if self.exe_path.is_none() {
|
|
||||||
return Err("should init the exe_path first".into());
|
if self.auto_launch.is_none() {
|
||||||
|
return Err("should init the auto launch first".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let exe_path = self.exe_path.clone().unwrap();
|
let auto_launch = self.auto_launch.clone().unwrap();
|
||||||
match startup::get_startup(&exe_path) {
|
|
||||||
Ok(sys_enable) => {
|
let is_enabled = auto_launch.is_enabled().unwrap_or(false);
|
||||||
if sys_enable || (!sys_enable && startup::set_startup(true, &exe_path).is_ok()) {
|
if !is_enabled {
|
||||||
Ok(())
|
if let Err(_) = auto_launch.enable() {
|
||||||
} else {
|
return Err("failed to enable auto-launch".into());
|
||||||
Err("failed to sync startup".into())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Err(_) => Err("failed to get system startup info".into()),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// update the startup
|
/// update the startup
|
||||||
fn update_startup(&mut self, enable: bool) -> Result<(), String> {
|
fn update_launch(&mut self, enable: bool) -> Result<(), String> {
|
||||||
let conf_enable = self.config.enable_self_startup.clone().unwrap_or(false);
|
let conf_enable = self.config.enable_auto_launch.clone().unwrap_or(false);
|
||||||
|
|
||||||
if enable == conf_enable {
|
if enable == conf_enable {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
if self.exe_path.is_none() {
|
|
||||||
return Err("should init the exe_path first".into());
|
let auto_launch = self.auto_launch.clone().unwrap();
|
||||||
}
|
|
||||||
let exe_path = self.exe_path.clone().unwrap();
|
let result = if enable {
|
||||||
match startup::set_startup(enable, &exe_path) {
|
auto_launch.enable()
|
||||||
|
} else {
|
||||||
|
auto_launch.disable()
|
||||||
|
};
|
||||||
|
|
||||||
|
match result {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(_) => Err("failed to set system startup info".into()),
|
Err(_) => Err("failed to set system startup info".into()),
|
||||||
}
|
}
|
||||||
@ -166,10 +174,10 @@ impl Verge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// should update system startup
|
// should update system startup
|
||||||
if patch.enable_self_startup.is_some() {
|
if patch.enable_auto_launch.is_some() {
|
||||||
let enable = patch.enable_self_startup.unwrap();
|
let enable = patch.enable_auto_launch.unwrap();
|
||||||
self.update_startup(enable)?;
|
self.update_launch(enable)?;
|
||||||
self.config.enable_self_startup = Some(enable);
|
self.config.enable_auto_launch = Some(enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
// should update system proxy
|
// should update system proxy
|
||||||
@ -187,7 +195,7 @@ impl Verge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// todo
|
// todo
|
||||||
// should update system proxt too
|
// should update system proxy too
|
||||||
if patch.system_proxy_bypass.is_some() {
|
if patch.system_proxy_bypass.is_some() {
|
||||||
self.config.system_proxy_bypass = patch.system_proxy_bypass;
|
self.config.system_proxy_bypass = patch.system_proxy_bypass;
|
||||||
}
|
}
|
||||||
@ -195,3 +203,14 @@ impl Verge {
|
|||||||
self.config.save_file()
|
self.config.save_file()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the target app_path
|
||||||
|
fn get_app_path(app_name: &str) -> String {
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
let ext = "";
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
let ext = ".app";
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
let ext = ".exe";
|
||||||
|
String::from(app_name) + ext
|
||||||
|
}
|
||||||
|
@ -4,5 +4,4 @@ pub mod fetch;
|
|||||||
pub mod init;
|
pub mod init;
|
||||||
pub mod resolve;
|
pub mod resolve;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
pub mod startup;
|
|
||||||
pub mod sysopt;
|
pub mod sysopt;
|
||||||
|
@ -9,6 +9,7 @@ pub fn resolve_setup(app: &App) {
|
|||||||
let window = app.get_window("main").unwrap();
|
let window = app.get_window("main").unwrap();
|
||||||
window.set_shadow(true);
|
window.set_shadow(true);
|
||||||
|
|
||||||
|
// enable system blur
|
||||||
use tauri_plugin_vibrancy::Vibrancy;
|
use tauri_plugin_vibrancy::Vibrancy;
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
window.apply_blur();
|
window.apply_blur();
|
||||||
@ -42,9 +43,9 @@ pub fn resolve_setup(app: &App) {
|
|||||||
log::error!("{}", err);
|
log::error!("{}", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
verge.set_exe_path(app.package_info());
|
|
||||||
verge.init_sysproxy(clash.info.port.clone());
|
verge.init_sysproxy(clash.info.port.clone());
|
||||||
if let Err(err) = verge.sync_startup() {
|
verge.init_launch(app.package_info());
|
||||||
|
if let Err(err) = verge.sync_launch() {
|
||||||
log::error!("{}", err);
|
log::error!("{}", err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,74 +0,0 @@
|
|||||||
use std::io;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
static APP_KEY: &str = "ClashVerge";
|
|
||||||
|
|
||||||
/// get the startup value
|
|
||||||
/// whether as same as the exe_path
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
pub fn get_startup(exe_path: &PathBuf) -> io::Result<bool> {
|
|
||||||
use winreg::enums::*;
|
|
||||||
use winreg::RegKey;
|
|
||||||
|
|
||||||
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
|
|
||||||
let cur_var = hkcu.open_subkey_with_flags(
|
|
||||||
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
|
|
||||||
KEY_READ,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
match cur_var.get_value::<String, _>(APP_KEY) {
|
|
||||||
Ok(path) => {
|
|
||||||
let exe_path = exe_path.clone();
|
|
||||||
let exe_path = exe_path.as_os_str().to_str().unwrap();
|
|
||||||
Ok(path == exe_path)
|
|
||||||
}
|
|
||||||
Err(_) => Ok(false),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// set the startup on windows
|
|
||||||
/// delete the reg key if disabled
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
pub fn set_startup(enable: bool, exe_path: &PathBuf) -> io::Result<()> {
|
|
||||||
use winreg::enums::*;
|
|
||||||
use winreg::RegKey;
|
|
||||||
|
|
||||||
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
|
|
||||||
let cur_var = hkcu.open_subkey_with_flags(
|
|
||||||
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
|
|
||||||
KEY_SET_VALUE,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
match enable {
|
|
||||||
true => {
|
|
||||||
let exe_path = exe_path.clone();
|
|
||||||
let exe_path = exe_path.as_os_str().to_str().unwrap();
|
|
||||||
cur_var.set_value::<&str, _>(APP_KEY, &exe_path)
|
|
||||||
}
|
|
||||||
false => cur_var.delete_value(APP_KEY),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// todo
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
pub fn get_startup(exe_path: &PathBuf) -> io::Result<bool> {
|
|
||||||
Ok(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// todo
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
pub fn set_startup(enable: bool, exe_path: &PathBuf) -> io::Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
#[test]
|
|
||||||
fn test() {
|
|
||||||
let path = PathBuf::from(r"D:\Software\Clash Verge\clash-verge.exe");
|
|
||||||
|
|
||||||
assert!(set_startup(true, &path).is_ok());
|
|
||||||
assert_eq!(get_startup(&path).unwrap(), true);
|
|
||||||
|
|
||||||
assert!(set_startup(false, &path).is_ok());
|
|
||||||
assert_eq!(get_startup(&path).unwrap(), false);
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user