2026-04-07 10:20:00 +08:00
|
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
|
use std::fs;
|
|
|
|
|
use std::path::PathBuf;
|
2026-04-07 10:42:37 +08:00
|
|
|
use tokio::signal;
|
2026-04-07 10:20:00 +08:00
|
|
|
use tokio::time;
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
|
|
|
struct Config {
|
|
|
|
|
debug_mode: bool,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Default for Config {
|
|
|
|
|
fn default() -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
debug_mode: false,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn get_config_path() -> PathBuf {
|
|
|
|
|
let exe_path = std::env::current_exe().expect("Failed to get executable path");
|
2026-04-07 10:42:37 +08:00
|
|
|
let drive = if let Some(parent) = exe_path.parent() {
|
|
|
|
|
let drive = parent.as_os_str().to_str().unwrap_or("C:/").split('\\').next().unwrap_or("C:");
|
|
|
|
|
std::path::Path::new(&format!("{}/", drive)).to_path_buf()
|
|
|
|
|
} else {
|
|
|
|
|
std::path::Path::new("C:/").to_path_buf()
|
|
|
|
|
};
|
2026-04-07 10:20:00 +08:00
|
|
|
let appdata = drive.join("AppData").join("Updater");
|
|
|
|
|
fs::create_dir_all(&appdata).expect("Failed to create config directory");
|
|
|
|
|
appdata.join("config.json")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn load_config() -> Config {
|
|
|
|
|
let config_path = get_config_path();
|
|
|
|
|
if config_path.exists() {
|
2026-04-07 10:42:37 +08:00
|
|
|
match fs::read_to_string(&config_path) {
|
|
|
|
|
Ok(content) => {
|
|
|
|
|
match serde_json::from_str(&content) {
|
|
|
|
|
Ok(config) => config,
|
|
|
|
|
Err(_) => Config::default(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Err(_) => Config::default(),
|
|
|
|
|
}
|
2026-04-07 10:20:00 +08:00
|
|
|
} else {
|
|
|
|
|
let default_config = Config::default();
|
2026-04-07 10:42:37 +08:00
|
|
|
match serde_json::to_string_pretty(&default_config) {
|
|
|
|
|
Ok(content) => {
|
|
|
|
|
match fs::write(&config_path, content) {
|
|
|
|
|
Ok(_) => default_config,
|
|
|
|
|
Err(_) => default_config,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
Err(_) => default_config,
|
|
|
|
|
}
|
2026-04-07 10:20:00 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-07 10:42:37 +08:00
|
|
|
async fn upgrade(debug_mode: bool) {
|
|
|
|
|
if debug_mode {
|
|
|
|
|
println!("开始升级");
|
|
|
|
|
}
|
2026-04-07 10:20:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
|
async fn main() {
|
|
|
|
|
let config = load_config();
|
|
|
|
|
|
2026-04-07 11:04:06 +08:00
|
|
|
if !config.debug_mode {
|
|
|
|
|
#[cfg(windows)]
|
|
|
|
|
{
|
|
|
|
|
use windows::Win32::System::Console;
|
|
|
|
|
use windows::Win32::Foundation::HWND;
|
|
|
|
|
unsafe {
|
|
|
|
|
let console = Console::GetConsoleWindow();
|
|
|
|
|
if console != HWND::default() {
|
|
|
|
|
let _ = Console::FreeConsole();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-07 10:42:37 +08:00
|
|
|
if config.debug_mode {
|
|
|
|
|
let mut interval = time::interval(time::Duration::from_secs(300));
|
|
|
|
|
loop {
|
|
|
|
|
tokio::select! {
|
|
|
|
|
_ = interval.tick() => {
|
|
|
|
|
upgrade(config.debug_mode).await;
|
|
|
|
|
}
|
|
|
|
|
_ = signal::ctrl_c() => {
|
|
|
|
|
println!("Received Ctrl+C, exiting...");
|
|
|
|
|
break;
|
|
|
|
|
}
|
2026-04-07 10:20:00 +08:00
|
|
|
}
|
|
|
|
|
}
|
2026-04-07 10:42:37 +08:00
|
|
|
} else {
|
|
|
|
|
let mut interval = time::interval(time::Duration::from_secs(300));
|
|
|
|
|
loop {
|
|
|
|
|
interval.tick().await;
|
|
|
|
|
upgrade(config.debug_mode).await;
|
|
|
|
|
}
|
2026-04-07 10:20:00 +08:00
|
|
|
}
|
|
|
|
|
}
|