mirror of
https://github.com/VirtualHotBar/NetMount.git
synced 2026-06-08 23:52:34 +08:00
use tauri-plugin-autostart
This commit is contained in:
51
src-tauri/Cargo.lock
generated
51
src-tauri/Cargo.lock
generated
@@ -101,6 +101,7 @@ dependencies = [
|
||||
"tar",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"tauri-plugin-autostart",
|
||||
"tauri-plugin-fs",
|
||||
"tauri-plugin-os",
|
||||
"tauri-plugin-process",
|
||||
@@ -295,6 +296,17 @@ version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
||||
|
||||
[[package]]
|
||||
name = "auto-launch"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f012b8cc0c850f34117ec8252a44418f2e34a2cf501de89e29b241ae5f79471"
|
||||
dependencies = [
|
||||
"dirs 4.0.0",
|
||||
"thiserror",
|
||||
"winreg 0.10.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.3.0"
|
||||
@@ -904,13 +916,22 @@ dependencies = [
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "4.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059"
|
||||
dependencies = [
|
||||
"dirs-sys 0.3.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "5.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
"dirs-sys 0.4.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -923,6 +944,17 @@ dependencies = [
|
||||
"dirs-sys-next",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.4.1"
|
||||
@@ -4190,6 +4222,21 @@ dependencies = [
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-autostart"
|
||||
version = "2.0.0-beta.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59f0c8ed07512164ce45d8c05b42def923da8ead753ebded7b74fe4c5cd99021"
|
||||
dependencies = [
|
||||
"auto-launch",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-plugin",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-fs"
|
||||
version = "2.0.0-beta.9"
|
||||
@@ -4674,7 +4721,7 @@ dependencies = [
|
||||
"cocoa",
|
||||
"core-graphics",
|
||||
"crossbeam-channel",
|
||||
"dirs",
|
||||
"dirs 5.0.1",
|
||||
"libappindicator",
|
||||
"muda",
|
||||
"objc",
|
||||
|
||||
@@ -47,7 +47,7 @@ tauri-plugin-shell = "2.0.0-beta.7"
|
||||
tauri-plugin-os = "2.0.0-beta.6"
|
||||
tauri-plugin-fs = "2.0.0-beta.9"
|
||||
tauri-plugin-process = "2.0.0-beta.6"
|
||||
# tauri-plugin-autostart = "2.0.0-beta.7"
|
||||
tauri-plugin-autostart = "2.0.0-beta.7"
|
||||
tauri-plugin-single-instance = "2.0.0-beta.9"
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
winreg = "0.10.1"
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -2422,6 +2422,54 @@
|
||||
"app:deny-version"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"autostart:default"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "autostart:allow-disable -> Enables the disable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"autostart:allow-disable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "autostart:allow-enable -> Enables the enable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"autostart:allow-enable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "autostart:allow-is-enabled -> Enables the is_enabled command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"autostart:allow-is-enabled"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "autostart:deny-disable -> Denies the disable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"autostart:deny-disable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "autostart:deny-enable -> Denies the enable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"autostart:deny-enable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "autostart:deny-is-enabled -> Denies the is_enabled command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"autostart:deny-is-enabled"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "event:default -> Default permissions for the plugin.",
|
||||
"type": "string",
|
||||
|
||||
@@ -2422,6 +2422,54 @@
|
||||
"app:deny-version"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"autostart:default"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "autostart:allow-disable -> Enables the disable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"autostart:allow-disable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "autostart:allow-enable -> Enables the enable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"autostart:allow-enable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "autostart:allow-is-enabled -> Enables the is_enabled command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"autostart:allow-is-enabled"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "autostart:deny-disable -> Denies the disable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"autostart:deny-disable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "autostart:deny-enable -> Denies the enable command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"autostart:deny-enable"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "autostart:deny-is-enabled -> Denies the is_enabled command without any pre-configured scope.",
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"autostart:deny-is-enabled"
|
||||
]
|
||||
},
|
||||
{
|
||||
"description": "event:default -> Default permissions for the plugin.",
|
||||
"type": "string",
|
||||
|
||||
@@ -1,205 +0,0 @@
|
||||
use std::env;
|
||||
use std::io;
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub fn set_autostart(enabled: bool) -> io::Result<()> {
|
||||
use std::fs::File;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::prelude::*;
|
||||
use std::path::Path;
|
||||
|
||||
let label = "com.vhbs.netmount"; // 你的程序标识符
|
||||
let exe_path = env::current_exe()?;
|
||||
let exe_path_str = exe_path.to_string_lossy().into_owned();
|
||||
|
||||
let plist_content = if enabled {
|
||||
let program_arguments = format!("\"{}\"", exe_path_str);
|
||||
format!(
|
||||
r#"
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>Label</key>
|
||||
<string>{}</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>{}</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
"#,
|
||||
label, program_arguments
|
||||
)
|
||||
} else {
|
||||
"".to_string() // 如果禁用自启动,则不需要创建plist文件
|
||||
};
|
||||
|
||||
let plist_path_str = format!(
|
||||
"{}/Library/LaunchAgents/{}.plist",
|
||||
std::env::var("HOME").expect("HOME is not set"),
|
||||
label
|
||||
);
|
||||
|
||||
if !plist_content.is_empty() {
|
||||
let plist_path = Path::new(&plist_path_str);
|
||||
|
||||
// 创建或覆盖plist文件
|
||||
let mut file = OpenOptions::new()
|
||||
.write(true)
|
||||
.create(true)
|
||||
.truncate(true)
|
||||
.open(plist_path)?;
|
||||
|
||||
// 使用let绑定创建一个较长生命周期的变量
|
||||
let mut file = file; // 重新绑定以保持借用有效
|
||||
|
||||
file.write_all(plist_content.as_bytes())?;
|
||||
|
||||
std::process::Command::new("launchctl")
|
||||
.arg("load")
|
||||
.arg(plist_path_str)
|
||||
.status()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
pub fn is_autostart() -> io::Result<bool> {
|
||||
let label = "com.vhbs.netmount"; // 你的程序标识符
|
||||
let output = std::process::Command::new("launchctl")
|
||||
.arg("list")
|
||||
.arg(label)
|
||||
.output()?;
|
||||
if output.status.success() {
|
||||
Ok(String::from_utf8_lossy(&output.stdout).contains(label))
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn set_autostart(enabled: bool) -> io::Result<()> {
|
||||
use std::{os::windows::process::CommandExt, process::Command};
|
||||
|
||||
let exe_path = env::current_exe()?;
|
||||
let exe_path_str = exe_path.to_string_lossy().into_owned();
|
||||
|
||||
let command = if enabled {
|
||||
format!(
|
||||
"reg add HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run /v NetMount /t REG_SZ /d \"{}\" /f",
|
||||
exe_path_str
|
||||
)
|
||||
} else {
|
||||
"reg delete HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run /v NetMount /f"
|
||||
.to_string()
|
||||
};
|
||||
|
||||
let cmd = Command::new("cmd")
|
||||
.arg("/C")
|
||||
.arg(command.clone())
|
||||
.creation_flags(0x08000000)
|
||||
.spawn();
|
||||
|
||||
let output = cmd.unwrap().wait_with_output()?;
|
||||
|
||||
if output.status.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!(
|
||||
"Failed to modify autostart setting. Command: '{}', Error: {}",
|
||||
command,
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub fn is_autostart() -> io::Result<bool> {
|
||||
extern crate winreg;
|
||||
use winreg::enums::*;
|
||||
use winreg::RegKey;
|
||||
|
||||
let app_name = "NetMount";
|
||||
let exe_path = env::current_exe()?;
|
||||
let exe_path_str = exe_path.to_string_lossy().into_owned();
|
||||
// 打开注册表的“Run”键
|
||||
let hkcu = RegKey::predef(HKEY_CURRENT_USER);
|
||||
let run_key = hkcu.open_subkey("Software\\Microsoft\\Windows\\CurrentVersion\\Run")?;
|
||||
|
||||
// 尝试获取传入的app_name的值
|
||||
match run_key.get_value::<String, _>(app_name) {
|
||||
Ok(path) => Ok(path == format!("\"{}\"", exe_path_str)), // 如果成功获取值,返回true
|
||||
Err(_) => Ok(false), // 如果获取失败,返回false
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn set_autostart(enabled: bool) -> io::Result<()> {
|
||||
use std::fs::File;
|
||||
use std::io::prelude::*;
|
||||
use std::path::Path;
|
||||
|
||||
let exe_path = env::current_exe()?;
|
||||
let exe_path_str = exe_path
|
||||
.to_str()
|
||||
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "Failed to read executable path"))?;
|
||||
|
||||
const SERVICE_FILE_PATH: &str = "/etc/systemd/system/netmount.service";
|
||||
|
||||
if enabled {
|
||||
// Create the service file
|
||||
let service_content = format!(
|
||||
"[Unit]
|
||||
Description=NetMount
|
||||
|
||||
[Service]
|
||||
ExecStart={}
|
||||
Restart=always
|
||||
User=root
|
||||
Group=root
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
",
|
||||
exe_path_str,
|
||||
);
|
||||
|
||||
let mut file = File::create(SERVICE_FILE_PATH)?;
|
||||
file.write_all(service_content.as_bytes())?;
|
||||
|
||||
println!("Service file created at {}", SERVICE_FILE_PATH);
|
||||
|
||||
// Inform the user about the need to manually run systemctl commands
|
||||
println!("Please execute the following commands to enable and start the service:");
|
||||
println!("sudo systemctl daemon-reload");
|
||||
println!("sudo systemctl enable --now netmount");
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
// Remove the service file if it exists
|
||||
if Path::new(SERVICE_FILE_PATH).exists() {
|
||||
std::fs::remove_file(SERVICE_FILE_PATH)?;
|
||||
println!("Service file removed.");
|
||||
} else {
|
||||
println!("Service file does not exist; no action taken.");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn is_autostart() -> io::Result<bool> {
|
||||
use std::path::Path;
|
||||
let file_path = format!("/etc/systemd/system/{}.service", "netmount");
|
||||
Ok(Path::new(&file_path).exists())
|
||||
}
|
||||
@@ -5,20 +5,19 @@ use std::path::PathBuf;
|
||||
use std::{env, fs::File, ops::Deref, path::Path, sync::RwLock};
|
||||
|
||||
use config::Config;
|
||||
use fs::{fs_exist_dir, fs_make_dir,read_json_file,write_json_file};
|
||||
use fs::{fs_exist_dir, fs_make_dir, read_json_file, write_json_file};
|
||||
use locale::Locale;
|
||||
use tray::Tray;
|
||||
|
||||
mod autostart;
|
||||
mod config;
|
||||
mod fs;
|
||||
mod locale;
|
||||
mod tray;
|
||||
mod utils;
|
||||
|
||||
use crate::autostart::is_autostart;
|
||||
use crate::autostart::set_autostart;
|
||||
use crate::utils::download_with_progress;
|
||||
use tauri_plugin_autostart::MacosLauncher;
|
||||
use tauri_plugin_autostart::ManagerExt;
|
||||
// use crate::utils::ensure_single_instance;
|
||||
#[cfg(target_os = "windows")]
|
||||
use crate::utils::find_first_available_drive_letter;
|
||||
@@ -180,6 +179,10 @@ pub fn init() -> anyhow::Result<()> {
|
||||
.plugin(tauri_plugin_single_instance::init(|app, _, _| {
|
||||
app.app_main_window().toggle_visibility(Some(true)).ok();
|
||||
}))
|
||||
.plugin(tauri_plugin_autostart::init(
|
||||
MacosLauncher::LaunchAgent,
|
||||
Some(vec![]),
|
||||
))
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
toggle_devtools,
|
||||
get_config,
|
||||
@@ -261,17 +264,22 @@ fn get_winfsp_install_state() -> Result<bool, usize> {
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn get_autostart_state() -> Result<bool, usize> {
|
||||
match is_autostart() {
|
||||
fn get_autostart_state(app: tauri::AppHandle<Runtime>) -> Result<bool, usize> {
|
||||
let autostart_manager = app.autolaunch();
|
||||
match autostart_manager.is_enabled() {
|
||||
Ok(is_enabled) => Ok(is_enabled),
|
||||
Err(_) => Ok(false),
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn set_autostart_state(enabled: bool) -> Result<(), ()> {
|
||||
let _ = set_autostart(enabled);
|
||||
Ok(())
|
||||
fn set_autostart_state(app: tauri::AppHandle<Runtime>, enabled: bool) -> Result<bool, ()> {
|
||||
let autostart_manager = app.autolaunch();
|
||||
Ok(if enabled {
|
||||
autostart_manager.enable().is_ok()
|
||||
} else {
|
||||
autostart_manager.disable().is_ok()
|
||||
})
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
|
||||
Reference in New Issue
Block a user