feat: Support Startup Script

This commit is contained in:
MystiPanda 2024-01-17 15:06:16 +08:00
parent b08333dccd
commit a8b11abec8
10 changed files with 119 additions and 5 deletions

View File

@ -39,7 +39,7 @@ tokio = { version = "1", features = ["full"] }
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
reqwest = { version = "0.11", features = ["json", "rustls-tls"] } reqwest = { version = "0.11", features = ["json", "rustls-tls"] }
sysproxy = { git="https://github.com/clash-verge-rev/sysproxy-rs", branch = "main" } sysproxy = { git="https://github.com/clash-verge-rev/sysproxy-rs", branch = "main" }
tauri = { version = "1.5", features = [ "notification-all", "icon-png", "clipboard-all", "global-shortcut-all", "process-all", "shell-all", "system-tray", "updater", "window-all"] } tauri = { version = "1.5", features = [ "dialog-open", "notification-all", "icon-png", "clipboard-all", "global-shortcut-all", "process-all", "shell-all", "system-tray", "updater", "window-all"] }
[target.'cfg(windows)'.dependencies] [target.'cfg(windows)'.dependencies]
runas = "=1.0.0" # 高版本会返回错误 Status runas = "=1.0.0" # 高版本会返回错误 Status

View File

@ -25,6 +25,9 @@ pub struct IVerge {
/// copy env type /// copy env type
pub env_type: Option<String>, pub env_type: Option<String>,
/// startup script path
pub startup_script: Option<String>,
/// enable traffic graph default is true /// enable traffic graph default is true
pub traffic_graph: Option<bool>, pub traffic_graph: Option<bool>,
@ -189,6 +192,7 @@ impl IVerge {
patch!(theme_mode); patch!(theme_mode);
patch!(tray_event); patch!(tray_event);
patch!(env_type); patch!(env_type);
patch!(startup_script);
patch!(traffic_graph); patch!(traffic_graph);
patch!(enable_memory_usage); patch!(enable_memory_usage);

View File

@ -8,7 +8,9 @@ use log4rs::append::file::FileAppender;
use log4rs::config::{Appender, Logger, Root}; use log4rs::config::{Appender, Logger, Root};
use log4rs::encode::pattern::PatternEncoder; use log4rs::encode::pattern::PatternEncoder;
use std::fs::{self, DirEntry}; use std::fs::{self, DirEntry};
use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
use tauri::api::process::Command;
/// initialize this instance's log file /// initialize this instance's log file
fn init_log() -> Result<()> { fn init_log() -> Result<()> {
@ -340,3 +342,44 @@ pub fn init_scheme() -> Result<()> {
pub fn init_scheme() -> Result<()> { pub fn init_scheme() -> Result<()> {
Ok(()) Ok(())
} }
pub fn startup_script() -> Result<()> {
let path = {
let verge = Config::verge();
let verge = verge.latest();
verge.startup_script.clone().unwrap_or("".to_string())
};
if !path.is_empty() {
let mut shell = "";
if path.ends_with(".sh") {
shell = "bash";
}
if path.ends_with(".ps1") {
shell = "powershell";
}
if path.ends_with(".bat") {
shell = "cmd";
}
if shell.is_empty() {
return Err(anyhow::anyhow!("unsupported script: {path}"));
}
let current_dir = PathBuf::from(path.clone());
if !current_dir.exists() {
return Err(anyhow::anyhow!("script not found: {path}"));
}
let current_dir = current_dir.parent();
match current_dir {
Some(dir) => {
let _ = Command::new(shell)
.current_dir(dir.to_path_buf())
.args(&[path])
.output()?;
}
None => {
let _ = Command::new(shell).args(&[path]).output()?;
}
}
}
Ok(())
}

View File

@ -44,7 +44,7 @@ pub fn resolve_setup(app: &mut App) {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
log_err!(init::init_service()); log_err!(init::init_service());
log_err!(init::init_scheme()); log_err!(init::init_scheme());
log_err!(init::startup_script());
// 处理随机端口 // 处理随机端口
let enable_random_port = Config::verge().latest().enable_random_port.unwrap_or(false); let enable_random_port = Config::verge().latest().enable_random_port.unwrap_or(false);

View File

@ -54,6 +54,10 @@
}, },
"notification": { "notification": {
"all": true "all": true
},
"dialog": {
"all": false,
"open": true
} }
}, },
"windows": [], "windows": [],

View File

@ -1,7 +1,15 @@
import { useRef } from "react"; import { useRef } from "react";
import { useLockFn } from "ahooks"; import { useLockFn } from "ahooks";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { IconButton, MenuItem, Select, Typography } from "@mui/material"; import { open } from "@tauri-apps/api/dialog";
import {
Button,
IconButton,
MenuItem,
Select,
Input,
Typography,
} from "@mui/material";
import { openAppDir, openCoreDir, openLogsDir } from "@/services/cmds"; import { openAppDir, openCoreDir, openLogsDir } from "@/services/cmds";
import { ArrowForward } from "@mui/icons-material"; import { ArrowForward } from "@mui/icons-material";
import { checkUpdate } from "@tauri-apps/api/updater"; import { checkUpdate } from "@tauri-apps/api/updater";
@ -30,7 +38,8 @@ const SettingVerge = ({ onError }: Props) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { verge, patchVerge, mutateVerge } = useVerge(); const { verge, patchVerge, mutateVerge } = useVerge();
const { theme_mode, language, tray_event, env_type } = verge ?? {}; const { theme_mode, language, tray_event, env_type, startup_script } =
verge ?? {};
const configRef = useRef<DialogRef>(null); const configRef = useRef<DialogRef>(null);
const hotkeyRef = useRef<DialogRef>(null); const hotkeyRef = useRef<DialogRef>(null);
const miscRef = useRef<DialogRef>(null); const miscRef = useRef<DialogRef>(null);
@ -125,7 +134,54 @@ const SettingVerge = ({ onError }: Props) => {
</Select> </Select>
</GuardState> </GuardState>
</SettingItem> </SettingItem>
<SettingItem label={t("Startup Script")}>
<GuardState
value={startup_script ?? ""}
onCatch={onError}
onFormat={(e: any) => e.target.value}
onChange={(e) => onChangeData({ startup_script: e })}
onGuard={(e) => patchVerge({ startup_script: e })}
>
<Input
value={startup_script}
disabled
endAdornment={
<>
<Button
onClick={async () => {
const path = await open({
directory: false,
multiple: false,
filters: [
{
name: "Shell Script",
extensions: ["sh", "bat", "ps1"],
},
],
});
if (path?.length) {
onChangeData({ startup_script: `${path}` });
patchVerge({ startup_script: `${path}` });
}
}}
>
{t("Browse")}
</Button>
{startup_script && (
<Button
onClick={async () => {
onChangeData({ startup_script: "" });
patchVerge({ startup_script: "" });
}}
>
{t("Clear")}
</Button>
)}
</>
}
></Input>
</GuardState>
</SettingItem>
<SettingItem label={t("Theme Setting")}> <SettingItem label={t("Theme Setting")}>
<IconButton <IconButton
color="inherit" color="inherit"

View File

@ -99,6 +99,8 @@
"Theme Mode": "Theme Mode", "Theme Mode": "Theme Mode",
"Tray Click Event": "Tray Click Event", "Tray Click Event": "Tray Click Event",
"Copy Env Type": "Copy Env Type", "Copy Env Type": "Copy Env Type",
"Startup Script": "Startup Script",
"Browse": "Browse",
"Show Main Window": "Show Main Window", "Show Main Window": "Show Main Window",
"Theme Setting": "Theme Setting", "Theme Setting": "Theme Setting",
"Layout Setting": "Layout Setting", "Layout Setting": "Layout Setting",

View File

@ -90,6 +90,8 @@
"Theme Mode": "Режим темы", "Theme Mode": "Режим темы",
"Tray Click Event": "Событие щелчка в лотке", "Tray Click Event": "Событие щелчка в лотке",
"Copy Env Type": "Скопировать тип Env", "Copy Env Type": "Скопировать тип Env",
"Startup Script": "Скрипт запуска",
"Browse": "Просмотреть",
"Show Main Window": "Показать главное окно", "Show Main Window": "Показать главное окно",
"Theme Setting": "Настройка темы", "Theme Setting": "Настройка темы",
"Hotkey Setting": "Настройка клавиатурных сокращений", "Hotkey Setting": "Настройка клавиатурных сокращений",

View File

@ -99,6 +99,8 @@
"Theme Mode": "主题模式", "Theme Mode": "主题模式",
"Tray Click Event": "托盘点击事件", "Tray Click Event": "托盘点击事件",
"Copy Env Type": "复制环境变量类型", "Copy Env Type": "复制环境变量类型",
"Startup Script": "启动脚本",
"Browse": "浏览",
"Show Main Window": "显示主窗口", "Show Main Window": "显示主窗口",
"Theme Setting": "主题设置", "Theme Setting": "主题设置",
"Layout Setting": "界面设置", "Layout Setting": "界面设置",

View File

@ -167,6 +167,7 @@ interface IVergeConfig {
language?: string; language?: string;
tray_event?: "main_window" | "system_proxy" | "tun_mode" | string; tray_event?: "main_window" | "system_proxy" | "tun_mode" | string;
env_type?: "bash" | "cmd" | "powershell" | string; env_type?: "bash" | "cmd" | "powershell" | string;
startup_script?: string;
clash_core?: string; clash_core?: string;
theme_mode?: "light" | "dark" | "system"; theme_mode?: "light" | "dark" | "system";
traffic_graph?: boolean; traffic_graph?: boolean;