mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 00:35:38 +08:00
feat: integrate tauri-plugin-clipboard-manager and add system info commands (#5593)
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -7578,6 +7578,7 @@ dependencies = [
|
|||||||
"parking_lot",
|
"parking_lot",
|
||||||
"sysinfo",
|
"sysinfo",
|
||||||
"tauri",
|
"tauri",
|
||||||
|
"tauri-plugin-clipboard-manager",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ clash-verge-types = { path = "crates/clash-verge-types" }
|
|||||||
tauri-plugin-clash-verge-sysinfo = { path = "crates/tauri-plugin-clash-verge-sysinfo" }
|
tauri-plugin-clash-verge-sysinfo = { path = "crates/tauri-plugin-clash-verge-sysinfo" }
|
||||||
|
|
||||||
tauri = { version = "2.9.3" }
|
tauri = { version = "2.9.3" }
|
||||||
|
tauri-plugin-clipboard-manager = "2.3.2"
|
||||||
parking_lot = { version = "0.12.5", features = ["hardware-lock-elision"] }
|
parking_lot = { version = "0.12.5", features = ["hardware-lock-elision"] }
|
||||||
anyhow = "1.0.100"
|
anyhow = "1.0.100"
|
||||||
criterion = { version = "0.7.0", features = ["async_tokio"] }
|
criterion = { version = "0.7.0", features = ["async_tokio"] }
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ rust-version.workspace = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tauri = { workspace = true }
|
tauri = { workspace = true }
|
||||||
|
tauri-plugin-clipboard-manager = { workspace = true }
|
||||||
parking_lot = { workspace = true }
|
parking_lot = { workspace = true }
|
||||||
sysinfo = { version = "0.37.2", features = ["network", "system"] }
|
sysinfo = { version = "0.37.2", features = ["network", "system"] }
|
||||||
|
|
||||||
|
|||||||
39
crates/tauri-plugin-clash-verge-sysinfo/src/commands.rs
Normal file
39
crates/tauri-plugin-clash-verge-sysinfo/src/commands.rs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
use parking_lot::RwLock;
|
||||||
|
use tauri::{AppHandle, Runtime, State, command};
|
||||||
|
use tauri_plugin_clipboard_manager::{ClipboardExt as _, Error};
|
||||||
|
|
||||||
|
use crate::Platform;
|
||||||
|
|
||||||
|
// TODO 迁移,让新的结构体允许通过 tauri command 正确使用 structure.field 方式获取信息
|
||||||
|
#[command]
|
||||||
|
pub fn get_system_info(state: State<'_, RwLock<Platform>>) -> Result<String, Error> {
|
||||||
|
Ok(state.inner().read().to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 获取应用的运行时间(毫秒)
|
||||||
|
#[command]
|
||||||
|
pub fn get_app_uptime(state: State<'_, RwLock<Platform>>) -> Result<u128, Error> {
|
||||||
|
Ok(state
|
||||||
|
.inner()
|
||||||
|
.read()
|
||||||
|
.appinfo
|
||||||
|
.app_startup_time
|
||||||
|
.elapsed()
|
||||||
|
.as_millis())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 检查应用是否以管理员身份运行
|
||||||
|
#[command]
|
||||||
|
pub fn app_is_admin(state: State<'_, RwLock<Platform>>) -> Result<bool, Error> {
|
||||||
|
Ok(state.inner().read().appinfo.app_is_admin)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
pub fn export_diagnostic_info<R: Runtime>(
|
||||||
|
app_handle: AppHandle<R>,
|
||||||
|
state: State<'_, RwLock<Platform>>,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let info = state.inner().read().to_string();
|
||||||
|
let clipboard = app_handle.clipboard();
|
||||||
|
clipboard.write_text(info)
|
||||||
|
}
|
||||||
@@ -3,6 +3,8 @@ use std::{
|
|||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub mod commands;
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use deelevate::{PrivilegeLevel, Token};
|
use deelevate::{PrivilegeLevel, Token};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
@@ -130,11 +132,24 @@ pub fn set_app_core_mode<R: Runtime>(app: &tauri::AppHandle<R>, mode: impl Into<
|
|||||||
spec.appinfo.app_core_mode = mode.into();
|
spec.appinfo.app_core_mode = mode.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_current_app_handle_admin<R: Runtime>(app: &tauri::AppHandle<R>) -> bool {
|
||||||
|
let platform_spec = app.state::<RwLock<Platform>>();
|
||||||
|
let spec = platform_spec.read();
|
||||||
|
spec.appinfo.app_is_admin
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
pub fn init<R: Runtime>() -> TauriPlugin<R> {
|
||||||
Builder::new("clash_verge_sysinfo")
|
Builder::<R>::new("clash_verge_sysinfo")
|
||||||
|
// TODO 现在 crate 还不是真正的 tauri 插件,必须由主 lib 自行注册
|
||||||
// TODO 从 clash-verge 中迁移获取系统信息的 commnand 并实现优雅 structure.field 访问
|
// TODO 从 clash-verge 中迁移获取系统信息的 commnand 并实现优雅 structure.field 访问
|
||||||
// .invoke_handler(tauri::generate_handler![greet])
|
// .invoke_handler(tauri::generate_handler![
|
||||||
|
// commands::get_system_info,
|
||||||
|
// commands::get_app_uptime,
|
||||||
|
// commands::app_is_admin,
|
||||||
|
// commands::export_diagnostic_info,
|
||||||
|
// ])
|
||||||
.setup(move |app, _api| {
|
.setup(move |app, _api| {
|
||||||
let app_version = app.package_info().version.to_string();
|
let app_version = app.package_info().version.to_string();
|
||||||
let is_admin = is_binary_admin();
|
let is_admin = is_binary_admin();
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ clash-verge-logging = { workspace = true }
|
|||||||
clash-verge-signal = { workspace = true }
|
clash-verge-signal = { workspace = true }
|
||||||
clash-verge-types = { workspace = true }
|
clash-verge-types = { workspace = true }
|
||||||
tauri-plugin-clash-verge-sysinfo = { workspace = true }
|
tauri-plugin-clash-verge-sysinfo = { workspace = true }
|
||||||
|
tauri-plugin-clipboard-manager = { workspace = true }
|
||||||
tauri = { workspace = true, features = [
|
tauri = { workspace = true, features = [
|
||||||
"protocol-asset",
|
"protocol-asset",
|
||||||
"devtools",
|
"devtools",
|
||||||
@@ -72,7 +73,6 @@ tauri-plugin-shell = "2.3.3"
|
|||||||
tauri-plugin-dialog = "2.4.2"
|
tauri-plugin-dialog = "2.4.2"
|
||||||
tauri-plugin-fs = "2.4.4"
|
tauri-plugin-fs = "2.4.4"
|
||||||
tauri-plugin-process = "2.3.1"
|
tauri-plugin-process = "2.3.1"
|
||||||
tauri-plugin-clipboard-manager = "2.3.2"
|
|
||||||
tauri-plugin-deep-link = "2.4.5"
|
tauri-plugin-deep-link = "2.4.5"
|
||||||
tauri-plugin-window-state = "2.4.1"
|
tauri-plugin-window-state = "2.4.1"
|
||||||
zip = "6.0.0"
|
zip = "6.0.0"
|
||||||
|
|||||||
@@ -1,59 +1,9 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use super::CmdResult;
|
use crate::core::{CoreManager, manager::RunningMode};
|
||||||
use crate::core::{CoreManager, handle, manager::RunningMode};
|
|
||||||
use clash_verge_logging::{Type, logging};
|
|
||||||
use parking_lot::RwLock;
|
|
||||||
use tauri::Manager as _;
|
|
||||||
use tauri_plugin_clash_verge_sysinfo::Platform;
|
|
||||||
use tauri_plugin_clipboard_manager::ClipboardExt as _;
|
|
||||||
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn export_diagnostic_info() -> CmdResult<()> {
|
|
||||||
let app_handle = handle::Handle::app_handle();
|
|
||||||
let info = app_handle.state::<RwLock<Platform>>().read().to_string();
|
|
||||||
|
|
||||||
let app_handle = handle::Handle::app_handle();
|
|
||||||
let cliboard = app_handle.clipboard();
|
|
||||||
if cliboard.write_text(info).is_err() {
|
|
||||||
logging!(error, Type::System, "Failed to write to clipboard");
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO 迁移,让新的结构体允许通过 tauri command 正确使用 structure.field 方式获取信息
|
|
||||||
#[tauri::command]
|
|
||||||
pub async fn get_system_info() -> CmdResult<String> {
|
|
||||||
let app_handle = handle::Handle::app_handle();
|
|
||||||
let info = app_handle.state::<RwLock<Platform>>().read().to_string();
|
|
||||||
Ok(info)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 获取当前内核运行模式
|
/// 获取当前内核运行模式
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn get_running_mode() -> Result<Arc<RunningMode>, String> {
|
pub async fn get_running_mode() -> Result<Arc<RunningMode>, String> {
|
||||||
Ok(CoreManager::global().get_running_mode())
|
Ok(CoreManager::global().get_running_mode())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 获取应用的运行时间(毫秒)
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn get_app_uptime() -> u128 {
|
|
||||||
let app_handle = handle::Handle::app_handle();
|
|
||||||
let startup_time = app_handle
|
|
||||||
.state::<RwLock<Platform>>()
|
|
||||||
.read()
|
|
||||||
.appinfo
|
|
||||||
.app_startup_time;
|
|
||||||
startup_time.elapsed().as_millis()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// 检查应用是否以管理员身份运行
|
|
||||||
#[tauri::command]
|
|
||||||
pub fn is_admin() -> bool {
|
|
||||||
let app_handle = handle::Handle::app_handle();
|
|
||||||
app_handle
|
|
||||||
.state::<RwLock<Platform>>()
|
|
||||||
.read()
|
|
||||||
.appinfo
|
|
||||||
.app_is_admin
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,9 +1,13 @@
|
|||||||
use super::{IClashTemp, IProfiles, IVerge};
|
use super::{IClashTemp, IProfiles, IVerge};
|
||||||
use crate::{
|
use crate::{
|
||||||
cmd,
|
|
||||||
config::{PrfItem, profiles_append_item_safe},
|
config::{PrfItem, profiles_append_item_safe},
|
||||||
constants::{files, timing},
|
constants::{files, timing},
|
||||||
core::{CoreManager, handle, service, tray, validate::CoreConfigValidator},
|
core::{
|
||||||
|
CoreManager,
|
||||||
|
handle::{self, Handle},
|
||||||
|
service, tray,
|
||||||
|
validate::CoreConfigValidator,
|
||||||
|
},
|
||||||
enhance,
|
enhance,
|
||||||
utils::{dirs, help},
|
utils::{dirs, help},
|
||||||
};
|
};
|
||||||
@@ -14,6 +18,7 @@ use clash_verge_logging::{Type, logging, logging_error};
|
|||||||
use clash_verge_types::runtime::IRuntime;
|
use clash_verge_types::runtime::IRuntime;
|
||||||
use smartstring::alias::String;
|
use smartstring::alias::String;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use tauri_plugin_clash_verge_sysinfo::is_current_app_handle_admin;
|
||||||
use tokio::sync::OnceCell;
|
use tokio::sync::OnceCell;
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
|
|
||||||
@@ -60,7 +65,10 @@ impl Config {
|
|||||||
Self::ensure_default_profile_items().await?;
|
Self::ensure_default_profile_items().await?;
|
||||||
|
|
||||||
// init Tun mode
|
// init Tun mode
|
||||||
if !cmd::system::is_admin() && service::is_service_available().await.is_err() {
|
let handle = Handle::app_handle();
|
||||||
|
let is_admin = is_current_app_handle_admin(handle);
|
||||||
|
let is_service_available = service::is_service_available().await.is_ok();
|
||||||
|
if !is_admin && !is_service_available {
|
||||||
let verge = Self::verge().await;
|
let verge = Self::verge().await;
|
||||||
verge.edit_draft(|d| {
|
verge.edit_draft(|d| {
|
||||||
d.enable_tun_mode = Some(false);
|
d.enable_tun_mode = Some(false);
|
||||||
|
|||||||
@@ -255,15 +255,9 @@ async fn reinstall_service() -> Result<()> {
|
|||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
fn linux_running_as_root() -> bool {
|
fn linux_running_as_root() -> bool {
|
||||||
use crate::core::handle;
|
use crate::core::handle;
|
||||||
use parking_lot::RwLock;
|
use tauri_plugin_clash_verge_sysinfo::is_current_app_handle_admin;
|
||||||
use tauri::Manager as _;
|
|
||||||
use tauri_plugin_clash_verge_sysinfo::Platform;
|
|
||||||
let app_handle = handle::Handle::app_handle();
|
let app_handle = handle::Handle::app_handle();
|
||||||
app_handle
|
is_current_app_handle_admin(app_handle)
|
||||||
.state::<RwLock<Platform>>()
|
|
||||||
.read()
|
|
||||||
.appinfo
|
|
||||||
.app_is_admin
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
use tauri::tray::TrayIconBuilder;
|
use tauri::tray::TrayIconBuilder;
|
||||||
|
use tauri_plugin_clash_verge_sysinfo::is_current_app_handle_admin;
|
||||||
use tauri_plugin_mihomo::models::Proxies;
|
use tauri_plugin_mihomo::models::Proxies;
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
@@ -303,8 +304,8 @@ impl Tray {
|
|||||||
let verge = Config::verge().await.latest_arc();
|
let verge = Config::verge().await.latest_arc();
|
||||||
let system_proxy = verge.enable_system_proxy.as_ref().unwrap_or(&false);
|
let system_proxy = verge.enable_system_proxy.as_ref().unwrap_or(&false);
|
||||||
let tun_mode = verge.enable_tun_mode.as_ref().unwrap_or(&false);
|
let tun_mode = verge.enable_tun_mode.as_ref().unwrap_or(&false);
|
||||||
let tun_mode_available =
|
let tun_mode_available = is_current_app_handle_admin(app_handle)
|
||||||
cmd::system::is_admin() || service::is_service_available().await.is_ok();
|
|| service::is_service_available().await.is_ok();
|
||||||
let mode = {
|
let mode = {
|
||||||
Config::clash()
|
Config::clash()
|
||||||
.await
|
.await
|
||||||
|
|||||||
@@ -137,6 +137,10 @@ mod app_init {
|
|||||||
pub fn generate_handlers()
|
pub fn generate_handlers()
|
||||||
-> impl Fn(tauri::ipc::Invoke<tauri::Wry>) -> bool + Send + Sync + 'static {
|
-> impl Fn(tauri::ipc::Invoke<tauri::Wry>) -> bool + Send + Sync + 'static {
|
||||||
tauri::generate_handler![
|
tauri::generate_handler![
|
||||||
|
tauri_plugin_clash_verge_sysinfo::commands::get_system_info,
|
||||||
|
tauri_plugin_clash_verge_sysinfo::commands::get_app_uptime,
|
||||||
|
tauri_plugin_clash_verge_sysinfo::commands::app_is_admin,
|
||||||
|
tauri_plugin_clash_verge_sysinfo::commands::export_diagnostic_info,
|
||||||
cmd::get_sys_proxy,
|
cmd::get_sys_proxy,
|
||||||
cmd::get_auto_proxy,
|
cmd::get_auto_proxy,
|
||||||
cmd::open_app_dir,
|
cmd::open_app_dir,
|
||||||
@@ -155,9 +159,7 @@ mod app_init {
|
|||||||
cmd::notify_ui_ready,
|
cmd::notify_ui_ready,
|
||||||
cmd::update_ui_stage,
|
cmd::update_ui_stage,
|
||||||
cmd::get_running_mode,
|
cmd::get_running_mode,
|
||||||
cmd::get_app_uptime,
|
|
||||||
cmd::get_auto_launch_status,
|
cmd::get_auto_launch_status,
|
||||||
cmd::is_admin,
|
|
||||||
cmd::entry_lightweight_mode,
|
cmd::entry_lightweight_mode,
|
||||||
cmd::exit_lightweight_mode,
|
cmd::exit_lightweight_mode,
|
||||||
cmd::install_service,
|
cmd::install_service,
|
||||||
@@ -218,8 +220,6 @@ mod app_init {
|
|||||||
cmd::list_webdav_backup,
|
cmd::list_webdav_backup,
|
||||||
cmd::delete_webdav_backup,
|
cmd::delete_webdav_backup,
|
||||||
cmd::restore_webdav_backup,
|
cmd::restore_webdav_backup,
|
||||||
cmd::export_diagnostic_info,
|
|
||||||
cmd::get_system_info,
|
|
||||||
cmd::get_unlock_items,
|
cmd::get_unlock_items,
|
||||||
cmd::check_media_unlock,
|
cmd::check_media_unlock,
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -540,7 +540,7 @@ export const exit_lightweight_mode = async () => {
|
|||||||
|
|
||||||
export const isAdmin = async () => {
|
export const isAdmin = async () => {
|
||||||
try {
|
try {
|
||||||
return await invoke<boolean>("is_admin");
|
return await invoke<boolean>("app_is_admin");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("检查管理员权限失败:", error);
|
console.error("检查管理员权限失败:", error);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
Reference in New Issue
Block a user